Commit ee7ce018 authored by David Woodhouse's avatar David Woodhouse

Merge shinybook.infradead.org:/home/dwmw2/bk/linus-2.6

into shinybook.infradead.org:/home/dwmw2/bk/mtd-2.6
parents 1db608d1 956846c2
...@@ -3578,7 +3578,6 @@ S: The Netherlands ...@@ -3578,7 +3578,6 @@ S: The Netherlands
N: David Woodhouse N: David Woodhouse
E: dwmw2@infradead.org E: dwmw2@infradead.org
E: dwmw2@redhat.com
D: ARCnet stuff, Applicom board driver, SO_BINDTODEVICE, D: ARCnet stuff, Applicom board driver, SO_BINDTODEVICE,
D: some Alpha platform porting from 2.0, Memory Technology Devices, D: some Alpha platform porting from 2.0, Memory Technology Devices,
D: Acquire watchdog timer, PC speaker driver maintenance, D: Acquire watchdog timer, PC speaker driver maintenance,
......
...@@ -1469,7 +1469,7 @@ S: Maintained ...@@ -1469,7 +1469,7 @@ S: Maintained
MEMORY TECHNOLOGY DEVICES MEMORY TECHNOLOGY DEVICES
P: David Woodhouse P: David Woodhouse
M: dwmw2@redhat.com M: dwmw2@infradead.org
W: http://www.linux-mtd.infradead.org/ W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
S: Maintained S: Maintained
......
/* Derived from Applicom driver ac.c for SCO Unix */ /* Derived from Applicom driver ac.c for SCO Unix */
/* Ported by David Woodhouse, Axiom (Cambridge) Ltd. */ /* Ported by David Woodhouse, Axiom (Cambridge) Ltd. */
/* dwmw2@redhat.com 30/8/98 */ /* dwmw2@infradead.org 30/8/98 */
/* $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $ */ /* $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $ */
/* This module is for Linux 2.1 and 2.2 series kernels. */ /* This module is for Linux 2.1 and 2.2 series kernels. */
/*****************************************************************************/ /*****************************************************************************/
......
# $Id: Kconfig,v 1.6 2004/08/09 13:19:42 dwmw2 Exp $ # $Id: Kconfig,v 1.7 2004/11/22 11:33:56 ijc Exp $
menu "Memory Technology Devices (MTD)" menu "Memory Technology Devices (MTD)"
...@@ -54,8 +54,8 @@ config MTD_REDBOOT_PARTS ...@@ -54,8 +54,8 @@ config MTD_REDBOOT_PARTS
depends on MTD_PARTITIONS depends on MTD_PARTITIONS
---help--- ---help---
RedBoot is a ROM monitor and bootloader which deals with multiple RedBoot is a ROM monitor and bootloader which deals with multiple
'images' in flash devices by putting a table in the last erase 'images' in flash devices by putting a table one of the erase
block of the device, similar to a partition table, which gives blocks on the device, similar to a partition table, which gives
the offsets, lengths and names of all the images stored in the the offsets, lengths and names of all the images stored in the
flash. flash.
...@@ -68,6 +68,23 @@ config MTD_REDBOOT_PARTS ...@@ -68,6 +68,23 @@ config MTD_REDBOOT_PARTS
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
example. example.
config MTD_REDBOOT_DIRECTORY_BLOCK
int "Location of RedBoot partition table"
depends on MTD_REDBOOT_PARTS
default "-1"
---help---
This option is the Linux counterpart to the
CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK RedBoot compile time
option.
The option specifies which Flash sectors holds the RedBoot
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 config MTD_REDBOOT_PARTS_UNALLOCATED
bool " Include unallocated flash regions" bool " Include unallocated flash regions"
depends on MTD_REDBOOT_PARTS depends on MTD_REDBOOT_PARTS
......
# drivers/mtd/chips/Kconfig # drivers/mtd/chips/Kconfig
# $Id: Kconfig,v 1.9 2004/07/16 15:32:14 dwmw2 Exp $ # $Id: Kconfig,v 1.13 2004/12/01 15:49:10 nico Exp $
menu "RAM/ROM/Flash chip drivers" menu "RAM/ROM/Flash chip drivers"
depends on MTD!=n depends on MTD!=n
...@@ -7,6 +7,7 @@ menu "RAM/ROM/Flash chip drivers" ...@@ -7,6 +7,7 @@ menu "RAM/ROM/Flash chip drivers"
config MTD_CFI config MTD_CFI
tristate "Detect flash chips by Common Flash Interface (CFI) probe" tristate "Detect flash chips by Common Flash Interface (CFI) probe"
depends on MTD depends on MTD
select MTD_GEN_PROBE
help help
The Common Flash Interface specification was developed by Intel, The Common Flash Interface specification was developed by Intel,
AMD and other flash manufactures that provides a universal method AMD and other flash manufactures that provides a universal method
...@@ -18,6 +19,7 @@ config MTD_CFI ...@@ -18,6 +19,7 @@ config MTD_CFI
config MTD_JEDECPROBE config MTD_JEDECPROBE
tristate "Detect non-CFI AMD/JEDEC-compatible flash chips" tristate "Detect non-CFI AMD/JEDEC-compatible flash chips"
depends on MTD depends on MTD
select MTD_GEN_PROBE
help help
This option enables JEDEC-style probing of flash chips which are not This option enables JEDEC-style probing of flash chips which are not
compatible with the Common Flash Interface, but will use the common compatible with the Common Flash Interface, but will use the common
...@@ -29,8 +31,6 @@ config MTD_JEDECPROBE ...@@ -29,8 +31,6 @@ config MTD_JEDECPROBE
config MTD_GEN_PROBE config MTD_GEN_PROBE
tristate tristate
default m if MTD_CFI!=y && !MTD_INTELPROBE && MTD_JEDECPROBE!=y && (MTD_CFI=m || MTD_JEDECPROBE=m)
default y if MTD_CFI=y || MTD_INTELPROBE || MTD_JEDECPROBE=y
config MTD_CFI_ADV_OPTIONS config MTD_CFI_ADV_OPTIONS
bool "Flash chip driver advanced configuration options" bool "Flash chip driver advanced configuration options"
...@@ -158,6 +158,7 @@ config MTD_CFI_I8 ...@@ -158,6 +158,7 @@ config MTD_CFI_I8
config MTD_CFI_INTELEXT config MTD_CFI_INTELEXT
tristate "Support for Intel/Sharp flash chips" tristate "Support for Intel/Sharp flash chips"
depends on MTD_GEN_PROBE depends on MTD_GEN_PROBE
select MTD_CFI_UTIL
help help
The Common Flash Interface defines a number of different command The Common Flash Interface defines a number of different command
sets which a CFI-compliant chip may claim to implement. This code sets which a CFI-compliant chip may claim to implement. This code
...@@ -167,6 +168,7 @@ config MTD_CFI_INTELEXT ...@@ -167,6 +168,7 @@ config MTD_CFI_INTELEXT
config MTD_CFI_AMDSTD config MTD_CFI_AMDSTD
tristate "Support for AMD/Fujitsu flash chips" tristate "Support for AMD/Fujitsu flash chips"
depends on MTD_GEN_PROBE depends on MTD_GEN_PROBE
select MTD_CFI_UTIL
help help
The Common Flash Interface defines a number of different command The Common Flash Interface defines a number of different command
sets which a CFI-compliant chip may claim to implement. This code sets which a CFI-compliant chip may claim to implement. This code
...@@ -197,6 +199,7 @@ config MTD_CFI_AMDSTD_RETRY_MAX ...@@ -197,6 +199,7 @@ config MTD_CFI_AMDSTD_RETRY_MAX
config MTD_CFI_STAA config MTD_CFI_STAA
tristate "Support for ST (Advanced Architecture) flash chips" tristate "Support for ST (Advanced Architecture) flash chips"
depends on MTD_GEN_PROBE depends on MTD_GEN_PROBE
select MTD_CFI_UTIL
help help
The Common Flash Interface defines a number of different command The Common Flash Interface defines a number of different command
sets which a CFI-compliant chip may claim to implement. This code sets which a CFI-compliant chip may claim to implement. This code
...@@ -204,8 +207,6 @@ config MTD_CFI_STAA ...@@ -204,8 +207,6 @@ config MTD_CFI_STAA
config MTD_CFI_UTIL config MTD_CFI_UTIL
tristate tristate
default y if MTD_CFI_INTELEXT=y || MTD_CFI_AMDSTD=y || MTD_CFI_STAA=y
default m if MTD_CFI_INTELEXT=m || MTD_CFI_AMDSTD=m || MTD_CFI_STAA=m
config MTD_RAM config MTD_RAM
tristate "Support for RAM chips in bus mapping" tristate "Support for RAM chips in bus mapping"
...@@ -272,5 +273,14 @@ config MTD_JEDEC ...@@ -272,5 +273,14 @@ config MTD_JEDEC
<http://www.jedec.org/> distributes the identification codes for the <http://www.jedec.org/> distributes the identification codes for the
chips. chips.
config MTD_XIP
bool "XIP aware MTD support"
depends on !SMP && MTD_CFI_INTELEXT && EXPERIMENTAL
default y if XIP_KERNEL
help
This allows MTD support to work with flash memory which is also
used for XIP purposes. If you're not sure what this is all about
then say N.
endmenu endmenu
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Author: Jonas Holmberg <jonas.holmberg@axis.com> * Author: Jonas Holmberg <jonas.holmberg@axis.com>
* *
* $Id: amd_flash.c,v 1.25 2004/08/09 13:19:43 dwmw2 Exp $ * $Id: amd_flash.c,v 1.26 2004/11/20 12:49:04 dwmw2 Exp $
* *
* Copyright (c) 2001 Axis Communications AB * Copyright (c) 2001 Axis Communications AB
* *
...@@ -1122,7 +1122,7 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip, ...@@ -1122,7 +1122,7 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip,
timeo = jiffies + (HZ * 20); timeo = jiffies + (HZ * 20);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule_timeout(HZ); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
while (flash_is_busy(map, adr, private->interleave)) { while (flash_is_busy(map, adr, private->interleave)) {
......
This diff is collapsed.
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* This code is GPL * This code is GPL
* *
* $Id: cfi_cmdset_0002.c,v 1.111 2004/11/16 18:29:00 dwmw2 Exp $ * $Id: cfi_cmdset_0002.c,v 1.114 2004/12/11 15:43:53 dedekind Exp $
* *
*/ */
...@@ -707,7 +707,7 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned ...@@ -707,7 +707,7 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
*/ */
unsigned long uWriteTimeout = ( HZ / 1000 ) + 1; unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
int ret = 0; int ret = 0;
map_word oldd, curd; map_word oldd;
int retry_cnt = 0; int retry_cnt = 0;
adr += chip->start; adr += chip->start;
...@@ -764,23 +764,11 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned ...@@ -764,23 +764,11 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
continue; continue;
} }
/* Test to see if toggling has stopped. */ if (chip_ready(map, adr))
oldd = map_read(map, adr);
curd = map_read(map, adr);
if (map_word_equal(map, curd, oldd)) {
/* Do we have the correct value? */
if (map_word_equal(map, curd, datum)) {
goto op_done; goto op_done;
}
/* Nope something has gone wrong. */
break;
}
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo))
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
break; break;
}
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
cfi_spin_unlock(chip->mutex); cfi_spin_unlock(chip->mutex);
...@@ -788,6 +776,8 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned ...@@ -788,6 +776,8 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
cfi_spin_lock(chip->mutex); cfi_spin_lock(chip->mutex);
} }
printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
/* reset on all failures. */ /* reset on all failures. */
map_write( map, CMD(0xF0), chip->start ); map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */ /* FIXME - should have reset delay before continuing */
...@@ -1173,8 +1163,7 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip) ...@@ -1173,8 +1163,7 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
chip->in_progress_block_addr = adr; chip->in_progress_block_addr = adr;
cfi_spin_unlock(chip->mutex); cfi_spin_unlock(chip->mutex);
set_current_state(TASK_UNINTERRUPTIBLE); msleep(chip->erase_time/2);
schedule_timeout((chip->erase_time*HZ)/(2*1000));
cfi_spin_lock(chip->mutex); cfi_spin_lock(chip->mutex);
timeo = jiffies + (HZ*20); timeo = jiffies + (HZ*20);
...@@ -1259,8 +1248,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u ...@@ -1259,8 +1248,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
chip->in_progress_block_addr = adr; chip->in_progress_block_addr = adr;
cfi_spin_unlock(chip->mutex); cfi_spin_unlock(chip->mutex);
set_current_state(TASK_UNINTERRUPTIBLE); msleep(chip->erase_time/2);
schedule_timeout((chip->erase_time*HZ)/(2*1000));
cfi_spin_lock(chip->mutex); cfi_spin_lock(chip->mutex);
timeo = jiffies + (HZ*20); timeo = jiffies + (HZ*20);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* (C) 2000 Red Hat. GPL'd * (C) 2000 Red Hat. GPL'd
* *
* $Id: cfi_cmdset_0020.c,v 1.16 2004/11/16 18:29:00 dwmw2 Exp $ * $Id: cfi_cmdset_0020.c,v 1.17 2004/11/20 12:49:04 dwmw2 Exp $
* *
* 10/10/2000 Nicolas Pitre <nico@cam.org> * 10/10/2000 Nicolas Pitre <nico@cam.org>
* - completely revamped method functions so they are aware and * - completely revamped method functions so they are aware and
...@@ -788,7 +788,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u ...@@ -788,7 +788,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
chip->state = FL_ERASING; chip->state = FL_ERASING;
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule_timeout(HZ); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
/* FIXME. Use a timer to check this, and return immediately. */ /* FIXME. Use a timer to check this, and return immediately. */
...@@ -1087,7 +1087,7 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un ...@@ -1087,7 +1087,7 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un
chip->state = FL_LOCKING; chip->state = FL_LOCKING;
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule_timeout(HZ); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
/* FIXME. Use a timer to check this, and return immediately. */ /* FIXME. Use a timer to check this, and return immediately. */
...@@ -1236,7 +1236,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, ...@@ -1236,7 +1236,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip,
chip->state = FL_UNLOCKING; chip->state = FL_UNLOCKING;
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule_timeout(HZ); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
/* FIXME. Use a timer to check this, and return immediately. */ /* FIXME. Use a timer to check this, and return immediately. */
......
/* /*
Common Flash Interface probe code. Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd. (C) 2000 Red Hat. GPL'd.
$Id: cfi_probe.c,v 1.79 2004/10/20 23:04:01 dwmw2 Exp $ $Id: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mtd/xip.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/cfi.h> #include <linux/mtd/cfi.h>
#include <linux/mtd/gen_probe.h> #include <linux/mtd/gen_probe.h>
...@@ -31,11 +32,47 @@ static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi); ...@@ -31,11 +32,47 @@ static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi);
struct mtd_info *cfi_probe(struct map_info *map); struct mtd_info *cfi_probe(struct map_info *map);
#ifdef CONFIG_MTD_XIP
/* only needed for short periods, so this is rather simple */
#define xip_disable() local_irq_disable()
#define xip_allowed(base, map) \
do { \
(void) map_read(map, base); \
asm volatile (".rep 8; nop; .endr"); \
local_irq_enable(); \
} while (0)
#define xip_enable(base, map, cfi) \
do { \
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); \
xip_allowed(base, map); \
} while (0)
#define xip_disable_qry(base, map, cfi) \
do { \
xip_disable(); \
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); \
cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); \
} while (0)
#else
#define xip_disable() do { } while (0)
#define xip_allowed(base, map) do { } while (0)
#define xip_enable(base, map, cfi) do { } while (0)
#define xip_disable_qry(base, map, cfi) do { } while (0)
#endif
/* check for QRY. /* check for QRY.
in: interleave,type,mode in: interleave,type,mode
ret: table index, <0 for error ret: table index, <0 for error
*/ */
static int qry_present(struct map_info *map, __u32 base, static int __xipram qry_present(struct map_info *map, __u32 base,
struct cfi_private *cfi) struct cfi_private *cfi)
{ {
int osf = cfi->interleave * cfi->device_type; // scale factor int osf = cfi->interleave * cfi->device_type; // scale factor
...@@ -59,10 +96,10 @@ static int qry_present(struct map_info *map, __u32 base, ...@@ -59,10 +96,10 @@ static int qry_present(struct map_info *map, __u32 base,
if (!map_word_equal(map, qry[2], val[2])) if (!map_word_equal(map, qry[2], val[2]))
return 0; return 0;
return 1; // nothing found return 1; // "QRY" found
} }
static int cfi_probe_chip(struct map_info *map, __u32 base, static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
unsigned long *chip_map, struct cfi_private *cfi) unsigned long *chip_map, struct cfi_private *cfi)
{ {
int i; int i;
...@@ -79,12 +116,16 @@ static int cfi_probe_chip(struct map_info *map, __u32 base, ...@@ -79,12 +116,16 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
(unsigned long)base + 0x55, map->size -1); (unsigned long)base + 0x55, map->size -1);
return 0; return 0;
} }
xip_disable();
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 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); cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
if (!qry_present(map,base,cfi)) if (!qry_present(map,base,cfi)) {
xip_enable(base, map, cfi);
return 0; return 0;
}
if (!cfi->numchips) { 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
...@@ -110,6 +151,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base, ...@@ -110,6 +151,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
/* If the QRY marker goes away, it's an alias */ /* If the QRY marker goes away, it's an alias */
if (!qry_present(map, start, cfi)) { if (!qry_present(map, start, cfi)) {
xip_allowed(base, map);
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
map->name, base, start); map->name, base, start);
return 0; return 0;
...@@ -122,6 +164,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base, ...@@ -122,6 +164,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
cfi_send_gen_cmd(0xFF, 0, start, 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)) { 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", printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
map->name, base, start); map->name, base, start);
return 0; return 0;
...@@ -137,6 +180,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base, ...@@ -137,6 +180,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
/* Put it back into Read Mode */ /* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 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); cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
xip_allowed(base, map);
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 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->name, cfi->interleave, cfi->device_type*8, base,
...@@ -145,7 +189,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base, ...@@ -145,7 +189,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
return 1; return 1;
} }
static int cfi_chip_setup(struct map_info *map, static int __xipram cfi_chip_setup(struct map_info *map,
struct cfi_private *cfi) struct cfi_private *cfi)
{ {
int ofs_factor = cfi->interleave*cfi->device_type; int ofs_factor = cfi->interleave*cfi->device_type;
...@@ -153,6 +197,7 @@ static int cfi_chip_setup(struct map_info *map, ...@@ -153,6 +197,7 @@ static int cfi_chip_setup(struct map_info *map,
int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor); int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
int i; int i;
xip_enable(base, map, cfi);
#ifdef DEBUG_CFI #ifdef DEBUG_CFI
printk("Number of erase regions: %d\n", num_erase_regions); printk("Number of erase regions: %d\n", num_erase_regions);
#endif #endif
...@@ -170,9 +215,29 @@ static int cfi_chip_setup(struct map_info *map, ...@@ -170,9 +215,29 @@ static int cfi_chip_setup(struct map_info *map,
cfi->cfi_mode = CFI_MODE_CFI; cfi->cfi_mode = CFI_MODE_CFI;
/* Read the CFI info structure */ /* Read the CFI info structure */
for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) { xip_disable_qry(base, map, cfi);
for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor); ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
}
/* Note we put the device back into Read Mode BEFORE going into Auto
* Select Mode, as some devices support nesting of modes, others
* don't. This way should always work.
* On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
* so should be treated as nops or illegal (and so put the device
* back into Read Mode, which is a nop in this case).
*/
cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
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);
/* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
/* ... even if it's an Intel chip */
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
xip_allowed(base, map);
/* Do any necessary byteswapping */ /* Do any necessary byteswapping */
cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID); cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
...@@ -198,25 +263,6 @@ static int cfi_chip_setup(struct map_info *map, ...@@ -198,25 +263,6 @@ static int cfi_chip_setup(struct map_info *map,
#endif #endif
} }
/* Note we put the device back into Read Mode BEFORE going into Auto
* Select Mode, as some devices support nesting of modes, others
* don't. This way should always work.
* On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
* so should be treated as nops or illegal (and so put the device
* back into Read Mode, which is a nop in this case).
*/
cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
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);
/* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
/* ... even if it's an Intel chip */
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 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->name, cfi->interleave, cfi->device_type*8, base,
map->bankwidth*8); map->bankwidth*8);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* This code is covered by the GPL. * This code is covered by the GPL.
* *
* $Id: cfi_util.c,v 1.5 2004/08/12 06:40:23 eric Exp $ * $Id: cfi_util.c,v 1.8 2004/12/14 19:55:56 nico Exp $
* *
*/ */
...@@ -22,13 +22,14 @@ ...@@ -22,13 +22,14 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mtd/xip.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/cfi.h> #include <linux/mtd/cfi.h>
#include <linux/mtd/compatmac.h> #include <linux/mtd/compatmac.h>
struct cfi_extquery * struct cfi_extquery *
cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
__u32 base = 0; // cfi->chips[0].start; __u32 base = 0; // cfi->chips[0].start;
...@@ -40,21 +41,35 @@ cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) ...@@ -40,21 +41,35 @@ cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
if (!adr) if (!adr)
goto out; goto out;
/* Switch it into Query Mode */
cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
extp = kmalloc(size, GFP_KERNEL); extp = kmalloc(size, GFP_KERNEL);
if (!extp) { if (!extp) {
printk(KERN_ERR "Failed to allocate memory\n"); printk(KERN_ERR "Failed to allocate memory\n");
goto out; goto out;
} }
#ifdef CONFIG_MTD_XIP
local_irq_disable();
#endif
/* Switch it into Query Mode */
cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
/* Read in the Extended Query Table */ /* Read in the Extended Query Table */
for (i=0; i<size; i++) { for (i=0; i<size; i++) {
((unsigned char *)extp)[i] = ((unsigned char *)extp)[i] =
cfi_read_query(map, base+((adr+i)*ofs_factor)); cfi_read_query(map, base+((adr+i)*ofs_factor));
} }
/* Make sure it returns to 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);
#ifdef CONFIG_MTD_XIP
(void) map_read(map, base);
asm volatile (".rep 8; nop; .endr");
local_irq_enable();
#endif
if (extp->MajorVersion != '1' || if (extp->MajorVersion != '1' ||
(extp->MinorVersion < '0' || extp->MinorVersion > '3')) { (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
printk(KERN_WARNING " Unknown %s Extended Query " printk(KERN_WARNING " Unknown %s Extended Query "
...@@ -62,15 +77,9 @@ cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) ...@@ -62,15 +77,9 @@ cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
extp->MinorVersion); extp->MinorVersion);
kfree(extp); kfree(extp);
extp = NULL; extp = NULL;
goto out;
} }
out: out: return extp;
/* Make sure it's in 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);
return extp;
} }
EXPORT_SYMBOL(cfi_read_pri); EXPORT_SYMBOL(cfi_read_pri);
...@@ -156,7 +165,6 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, ...@@ -156,7 +165,6 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
i=first; i=first;
while(len) { while(len) {
unsigned long chipmask;
int size = regions[i].erasesize; int size = regions[i].erasesize;
ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk); ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
...@@ -165,10 +173,10 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, ...@@ -165,10 +173,10 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
return ret; return ret;
adr += size; adr += size;
ofs += size;
len -= size; len -= size;
chipmask = (1 << cfi->chipshift) - 1; if (ofs == regions[i].offset + size * regions[i].numblocks)
if ((adr & chipmask) == ((regions[i].offset + size * regions[i].numblocks) & chipmask))
i++; i++;
if (adr >> cfi->chipshift) { if (adr >> cfi->chipshift) {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* not going to guess how to send commands to them, plus I expect they will * not going to guess how to send commands to them, plus I expect they will
* all speak CFI.. * all speak CFI..
* *
* $Id: jedec.c,v 1.21 2004/08/09 13:19:43 dwmw2 Exp $ * $Id: jedec.c,v 1.22 2005/01/05 18:05:11 dwmw2 Exp $
*/ */
#include <linux/init.h> #include <linux/init.h>
...@@ -529,7 +529,7 @@ static int jedec_probe32(struct map_info *map,unsigned long base, ...@@ -529,7 +529,7 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
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) size_t *retlen, u_char *buf)
{ {
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
map_copy_from(map, buf, from, len); map_copy_from(map, buf, from, len);
*retlen = len; *retlen = len;
...@@ -541,8 +541,8 @@ static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -541,8 +541,8 @@ static int jedec_read(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, static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf) size_t *retlen, u_char *buf)
{ {
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv; struct jedec_private *priv = map->fldrv_priv;
*retlen = 0; *retlen = 0;
while (len > 0) while (len > 0)
...@@ -593,8 +593,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) ...@@ -593,8 +593,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
unsigned long NoTime = 0; unsigned long NoTime = 0;
unsigned long start = instr->addr, len = instr->len; unsigned long start = instr->addr, len = instr->len;
unsigned int I; unsigned int I;
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv; struct jedec_private *priv = map->fldrv_priv;
// Verify the arguments.. // Verify the arguments..
if (start + len > mtd->size || if (start + len > mtd->size ||
...@@ -800,8 +800,8 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, ...@@ -800,8 +800,8 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
#define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) #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)) #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv; struct jedec_private *priv = map->fldrv_priv;
unsigned long base; unsigned long base;
unsigned long off; unsigned long off;
size_t save_len = len; size_t save_len = len;
......
/* /*
Common Flash Interface probe code. Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd. (C) 2000 Red Hat. GPL'd.
$Id: jedec_probe.c,v 1.58 2004/11/16 18:29:00 dwmw2 Exp $ $Id: jedec_probe.c,v 1.61 2004/11/19 20:52:16 thayne Exp $
See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
for the standard this probe goes back to. for the standard this probe goes back to.
...@@ -227,6 +227,11 @@ static const struct unlock_addr unlock_addrs[] = { ...@@ -227,6 +227,11 @@ static const struct unlock_addr unlock_addrs[] = {
[MTD_UADDR_DONT_CARE] = { [MTD_UADDR_DONT_CARE] = {
.addr1 = 0x0000, /* Doesn't matter which address */ .addr1 = 0x0000, /* Doesn't matter which address */
.addr2 = 0x0000 /* is used - must be last entry */ .addr2 = 0x0000 /* is used - must be last entry */
},
[MTD_UADDR_UNNECESSARY] = {
.addr1 = 0x0000,
.addr2 = 0x0000
} }
}; };
...@@ -514,15 +519,20 @@ static const struct amd_flash_info jedec_table[] = { ...@@ -514,15 +519,20 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x10000,8), ERASEINFO(0x10000,8),
} }
}, { }, {
mfr_id: MANUFACTURER_AMD, .mfr_id = MANUFACTURER_AMD,
dev_id: AM29F002T, .dev_id = AM29F002T,
name: "AMD AM29F002T", .name = "AMD AM29F002T",
DevSize: SIZE_256KiB, .uaddr = {
NumEraseRegions: 4, [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
regions: {ERASEINFO(0x10000,3), },
.DevSize = SIZE_256KiB,
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 4,
.regions = {
ERASEINFO(0x10000,3),
ERASEINFO(0x08000,1), ERASEINFO(0x08000,1),
ERASEINFO(0x02000,2), ERASEINFO(0x02000,2),
ERASEINFO(0x04000,1) ERASEINFO(0x04000,1),
} }
}, { }, {
.mfr_id = MANUFACTURER_ATMEL, .mfr_id = MANUFACTURER_ATMEL,
...@@ -770,15 +780,20 @@ static const struct amd_flash_info jedec_table[] = { ...@@ -770,15 +780,20 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x04000,1) ERASEINFO(0x04000,1)
} }
}, { }, {
mfr_id: MANUFACTURER_HYUNDAI, .mfr_id = MANUFACTURER_HYUNDAI,
dev_id: HY29F002T, .dev_id = HY29F002T,
name: "Hyundai HY29F002T", .name = "Hyundai HY29F002T",
DevSize: SIZE_256KiB, .uaddr = {
NumEraseRegions: 4, [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
regions: {ERASEINFO(0x10000,3), },
.DevSize = SIZE_256KiB,
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 4,
.regions = {
ERASEINFO(0x10000,3),
ERASEINFO(0x08000,1), ERASEINFO(0x08000,1),
ERASEINFO(0x02000,2), ERASEINFO(0x02000,2),
ERASEINFO(0x04000,1) ERASEINFO(0x04000,1),
} }
}, { }, {
.mfr_id = MANUFACTURER_INTEL, .mfr_id = MANUFACTURER_INTEL,
...@@ -1177,15 +1192,20 @@ static const struct amd_flash_info jedec_table[] = { ...@@ -1177,15 +1192,20 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x10000,7), ERASEINFO(0x10000,7),
} }
}, { }, {
mfr_id: MANUFACTURER_MACRONIX, .mfr_id = MANUFACTURER_MACRONIX,
dev_id: MX29F002T, .dev_id = MX29F002T,
name: "Macronix MX29F002T", .name = "Macronix MX29F002T",
DevSize: SIZE_256KiB, .uaddr = {
NumEraseRegions: 4, [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
regions: {ERASEINFO(0x10000,3), },
.DevSize = SIZE_256KiB,
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 4,
.regions = {
ERASEINFO(0x10000,3),
ERASEINFO(0x08000,1), ERASEINFO(0x08000,1),
ERASEINFO(0x02000,2), ERASEINFO(0x02000,2),
ERASEINFO(0x04000,1) ERASEINFO(0x04000,1),
} }
}, { }, {
.mfr_id = MANUFACTURER_PMC, .mfr_id = MANUFACTURER_PMC,
...@@ -1780,7 +1800,6 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) ...@@ -1780,7 +1800,6 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
return 0; return 0;
} }
/* Mask out address bits which are smaller than the device type */
p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1; p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2; p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
...@@ -1923,7 +1942,6 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, ...@@ -1923,7 +1942,6 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
if (MTD_UADDR_UNNECESSARY == uaddr_idx) if (MTD_UADDR_UNNECESSARY == uaddr_idx)
return 0; return 0;
/* Mask out address bits which are smaller than the device type */
cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1; cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2; cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
} }
......
/* /*
* Common code to handle map devices which are simple RAM * Common code to handle map devices which are simple RAM
* (C) 2000 Red Hat. GPL'd. * (C) 2000 Red Hat. GPL'd.
* $Id: map_ram.c,v 1.21 2004/11/16 18:29:00 dwmw2 Exp $ * $Id: map_ram.c,v 1.22 2005/01/05 18:05:12 dwmw2 Exp $
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -83,7 +83,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map) ...@@ -83,7 +83,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{ {
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
map_copy_from(map, buf, from, len); map_copy_from(map, buf, from, len);
*retlen = len; *retlen = len;
...@@ -92,7 +92,7 @@ static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *r ...@@ -92,7 +92,7 @@ static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *r
static int mapram_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) static int mapram_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
{ {
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
map_copy_to(map, to, buf, len); map_copy_to(map, to, buf, len);
*retlen = len; *retlen = len;
...@@ -103,7 +103,7 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr) ...@@ -103,7 +103,7 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
{ {
/* Yeah, it's inefficient. Who cares? It's faster than a _real_ /* Yeah, it's inefficient. Who cares? It's faster than a _real_
flash erase. */ flash erase. */
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
map_word allff; map_word allff;
unsigned long i; unsigned long i;
......
/* /*
* Common code to handle map devices which are simple ROM * Common code to handle map devices which are simple ROM
* (C) 2000 Red Hat. GPL'd. * (C) 2000 Red Hat. GPL'd.
* $Id: map_rom.c,v 1.22 2004/11/16 18:29:00 dwmw2 Exp $ * $Id: map_rom.c,v 1.23 2005/01/05 18:05:12 dwmw2 Exp $
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -57,7 +57,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map) ...@@ -57,7 +57,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{ {
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
map_copy_from(map, buf, from, len); map_copy_from(map, buf, from, len);
*retlen = len; *retlen = len;
......
/* /*
* $Id: cmdlinepart.c,v 1.16 2004/11/16 18:28:59 dwmw2 Exp $ * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $
* *
* Read flash partition table from command line * Read flash partition table from command line
* *
...@@ -338,8 +338,10 @@ static int parse_cmdline_partitions(struct mtd_info *master, ...@@ -338,8 +338,10 @@ 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, * main.c::checksetup(). Note that we can not yet kmalloc() anything,
* so we only save the commandline for later processing. * so we only save the commandline for later processing.
*
* This function needs to be visible for bootloaders.
*/ */
static int mtdpart_setup(char *s) int mtdpart_setup(char *s)
{ {
cmdline = s; cmdline = s;
return 1; return 1;
......
# drivers/mtd/maps/Kconfig # drivers/mtd/maps/Kconfig
# $Id: Kconfig,v 1.13 2004/10/01 21:47:13 gleixner Exp $ # $Id: Kconfig,v 1.15 2004/12/22 17:51:15 joern Exp $
menu "Self-contained MTD device drivers" menu "Self-contained MTD device drivers"
depends on MTD!=n depends on MTD!=n
...@@ -125,11 +125,22 @@ config MTD_BLKMTD ...@@ -125,11 +125,22 @@ config MTD_BLKMTD
Testing MTD users (eg JFFS2) on large media and media that might Testing MTD users (eg JFFS2) on large media and media that might
be removed during a write (using the floppy drive). be removed during a write (using the floppy drive).
config MTD_BLOCK2MTD
tristate "MTD using block device (rewrite)"
depends on MTD || EXPERIMENTAL
help
This driver is basically the same at MTD_BLKMTD above, but
experienced some interface changes plus serious speedups. In
the long term, it should replace MTD_BLKMTD. Right now, you
shouldn't entrust important data to it yet.
comment "Disk-On-Chip Device Drivers" comment "Disk-On-Chip Device Drivers"
config MTD_DOC2000 config MTD_DOC2000
tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)" tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)"
depends on MTD depends on MTD
select MTD_DOCPROBE
select MTD_NAND_IDS
---help--- ---help---
This provides an MTD device driver for the M-Systems DiskOnChip This provides an MTD device driver for the M-Systems DiskOnChip
2000 and Millennium devices. Originally designed for the DiskOnChip 2000 and Millennium devices. Originally designed for the DiskOnChip
...@@ -151,6 +162,8 @@ config MTD_DOC2000 ...@@ -151,6 +162,8 @@ config MTD_DOC2000
config MTD_DOC2001 config MTD_DOC2001
tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)" tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)"
depends on MTD depends on MTD
select MTD_DOCPROBE
select MTD_NAND_IDS
---help--- ---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 DiskOnChip Millennium devices. Use this if you have problems with
...@@ -171,6 +184,8 @@ config MTD_DOC2001 ...@@ -171,6 +184,8 @@ config MTD_DOC2001
config MTD_DOC2001PLUS config MTD_DOC2001PLUS
tristate "M-Systems Disk-On-Chip Millennium Plus" tristate "M-Systems Disk-On-Chip Millennium Plus"
depends on MTD depends on MTD
select MTD_DOCPROBE
select MTD_NAND_IDS
---help--- ---help---
This provides an MTD device driver for the M-Systems DiskOnChip This provides an MTD device driver for the M-Systems DiskOnChip
Millennium Plus devices. Millennium Plus devices.
...@@ -186,17 +201,10 @@ config MTD_DOC2001PLUS ...@@ -186,17 +201,10 @@ config MTD_DOC2001PLUS
config MTD_DOCPROBE config MTD_DOCPROBE
tristate tristate
default m if MTD_DOC2001!=y && MTD_DOC2000!=y && MTD_DOC2001PLUS!=y && (MTD_DOC2001=m || MTD_DOC2000=m || MTD_DOC2001PLUS=m) select MTD_DOCECC
default y if MTD_DOC2001=y || MTD_DOC2000=y || MTD_DOC2001PLUS=y
help
This isn't a real config option; it's derived.
config MTD_DOCECC config MTD_DOCECC
tristate tristate
default m if MTD_DOCPROBE=m
default y if MTD_DOCPROBE=y
help
This isn't a real config option; it's derived.
config MTD_DOCPROBE_ADVANCED config MTD_DOCPROBE_ADVANCED
bool "Advanced detection options for DiskOnChip" bool "Advanced detection options for DiskOnChip"
......
# #
# linux/drivers/devices/Makefile # linux/drivers/devices/Makefile
# #
# $Id: Makefile.common,v 1.6 2004/07/12 16:07:30 dwmw2 Exp $ # $Id: Makefile.common,v 1.7 2004/12/22 17:51:15 joern Exp $
# *** BIG UGLY NOTE *** # *** BIG UGLY NOTE ***
# #
...@@ -22,3 +22,4 @@ obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o ...@@ -22,3 +22,4 @@ obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o
obj-$(CONFIG_MTD_MTDRAM) += mtdram.o obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
obj-$(CONFIG_MTD_LART) += lart.o obj-$(CONFIG_MTD_LART) += lart.o
obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o
obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
This diff is collapsed.
This diff is collapsed.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc. * (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
* *
* $Id: doc2000.c,v 1.64 2004/11/16 18:29:01 dwmw2 Exp $ * $Id: doc2000.c,v 1.66 2005/01/05 18:05:12 dwmw2 Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -527,14 +527,14 @@ static const char im_name[] = "DoC2k_init"; ...@@ -527,14 +527,14 @@ static const char im_name[] = "DoC2k_init";
*/ */
static void DoC2k_init(struct mtd_info *mtd) static void DoC2k_init(struct mtd_info *mtd)
{ {
struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *this = mtd->priv;
struct DiskOnChip *old = NULL; struct DiskOnChip *old = NULL;
int maxchips; int maxchips;
/* We must avoid being called twice for the same device. */ /* We must avoid being called twice for the same device. */
if (doc2klist) if (doc2klist)
old = (struct DiskOnChip *) doc2klist->priv; old = doc2klist->priv;
while (old) { while (old) {
if (DoC2k_is_alias(old, this)) { if (DoC2k_is_alias(old, this)) {
...@@ -546,7 +546,7 @@ static void DoC2k_init(struct mtd_info *mtd) ...@@ -546,7 +546,7 @@ static void DoC2k_init(struct mtd_info *mtd)
return; return;
} }
if (old->nextdoc) if (old->nextdoc)
old = (struct DiskOnChip *) old->nextdoc->priv; old = old->nextdoc->priv;
else else
old = NULL; old = NULL;
} }
...@@ -633,7 +633,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -633,7 +633,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, 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) size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
{ {
struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
struct Nand *mychip; struct Nand *mychip;
unsigned char syndrome[6]; unsigned char syndrome[6];
...@@ -790,7 +790,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -790,7 +790,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
size_t * retlen, const u_char * buf, size_t * retlen, const u_char * buf,
u_char * eccbuf, struct nand_oobinfo *oobsel) u_char * eccbuf, struct nand_oobinfo *oobsel)
{ {
struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *this = mtd->priv;
int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
volatile char dummy; volatile char dummy;
...@@ -1033,7 +1033,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, ...@@ -1033,7 +1033,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t * retlen, u_char * buf) size_t * retlen, u_char * buf)
{ {
struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *this = mtd->priv;
int len256 = 0, ret; int len256 = 0, ret;
struct Nand *mychip; struct Nand *mychip;
...@@ -1091,7 +1091,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -1091,7 +1091,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len, static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t * retlen, const u_char * buf) size_t * retlen, const u_char * buf)
{ {
struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *this = mtd->priv;
int len256 = 0; int len256 = 0;
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift]; struct Nand *mychip = &this->chips[ofs >> this->chipshift];
...@@ -1194,7 +1194,7 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -1194,7 +1194,7 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t * retlen, const u_char * buf) size_t * retlen, const u_char * buf)
{ {
struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *this = mtd->priv;
int ret; int ret;
down(&this->lock); down(&this->lock);
...@@ -1206,7 +1206,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -1206,7 +1206,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
{ {
struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; struct DiskOnChip *this = mtd->priv;
__u32 ofs = instr->addr; __u32 ofs = instr->addr;
__u32 len = instr->len; __u32 len = instr->len;
volatile int dummy; volatile int dummy;
...@@ -1288,7 +1288,7 @@ static void __exit cleanup_doc2000(void) ...@@ -1288,7 +1288,7 @@ static void __exit cleanup_doc2000(void)
struct DiskOnChip *this; struct DiskOnChip *this;
while ((mtd = doc2klist)) { while ((mtd = doc2klist)) {
this = (struct DiskOnChip *) mtd->priv; this = mtd->priv;
doc2klist = this->nextdoc; doc2klist = this->nextdoc;
del_mtd_device(mtd); del_mtd_device(mtd);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc. * (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
* *
* $Id: doc2001.c,v 1.46 2004/11/16 18:29:01 dwmw2 Exp $ * $Id: doc2001.c,v 1.48 2005/01/05 18:05:12 dwmw2 Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -335,12 +335,12 @@ static const char im_name[] = "DoCMil_init"; ...@@ -335,12 +335,12 @@ static const char im_name[] = "DoCMil_init";
*/ */
static void DoCMil_init(struct mtd_info *mtd) static void DoCMil_init(struct mtd_info *mtd)
{ {
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
struct DiskOnChip *old = NULL; struct DiskOnChip *old = NULL;
/* We must avoid being called twice for the same device. */ /* We must avoid being called twice for the same device. */
if (docmillist) if (docmillist)
old = (struct DiskOnChip *)docmillist->priv; old = docmillist->priv;
while (old) { while (old) {
if (DoCMil_is_alias(this, old)) { if (DoCMil_is_alias(this, old)) {
...@@ -351,7 +351,7 @@ static void DoCMil_init(struct mtd_info *mtd) ...@@ -351,7 +351,7 @@ static void DoCMil_init(struct mtd_info *mtd)
return; return;
} }
if (old->nextdoc) if (old->nextdoc)
old = (struct DiskOnChip *)old->nextdoc->priv; old = old->nextdoc->priv;
else else
old = NULL; old = NULL;
} }
...@@ -416,7 +416,7 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, ...@@ -416,7 +416,7 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
int i, ret; int i, ret;
volatile char dummy; volatile char dummy;
unsigned char syndrome[6]; unsigned char syndrome[6];
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[from >> (this->chipshift)]; struct Nand *mychip = &this->chips[from >> (this->chipshift)];
...@@ -542,7 +542,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, ...@@ -542,7 +542,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
{ {
int i,ret = 0; int i,ret = 0;
volatile char dummy; volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[to >> (this->chipshift)]; struct Nand *mychip = &this->chips[to >> (this->chipshift)];
...@@ -677,7 +677,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -677,7 +677,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
int i; int i;
#endif #endif
volatile char dummy; volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift]; struct Nand *mychip = &this->chips[ofs >> this->chipshift];
...@@ -729,7 +729,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -729,7 +729,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
#endif #endif
volatile char dummy; volatile char dummy;
int ret = 0; int ret = 0;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift]; struct Nand *mychip = &this->chips[ofs >> this->chipshift];
...@@ -796,7 +796,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -796,7 +796,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
int doc_erase (struct mtd_info *mtd, struct erase_info *instr) int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
{ {
volatile char dummy; volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
__u32 ofs = instr->addr; __u32 ofs = instr->addr;
__u32 len = instr->len; __u32 len = instr->len;
void __iomem *docptr = this->virtadr; void __iomem *docptr = this->virtadr;
...@@ -868,7 +868,7 @@ static void __exit cleanup_doc2001(void) ...@@ -868,7 +868,7 @@ static void __exit cleanup_doc2001(void)
struct DiskOnChip *this; struct DiskOnChip *this;
while ((mtd=docmillist)) { while ((mtd=docmillist)) {
this = (struct DiskOnChip *)mtd->priv; this = mtd->priv;
docmillist = this->nextdoc; docmillist = this->nextdoc;
del_mtd_device(mtd); del_mtd_device(mtd);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* (c) 1999 Machine Vision Holdings, Inc. * (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
* *
* $Id: doc2001plus.c,v 1.11 2004/11/16 18:29:01 dwmw2 Exp $ * $Id: doc2001plus.c,v 1.13 2005/01/05 18:05:12 dwmw2 Exp $
* *
* Released under GPL * Released under GPL
*/ */
...@@ -190,7 +190,7 @@ static int DoC_SelectFloor(void __iomem * docptr, int floor) ...@@ -190,7 +190,7 @@ static int DoC_SelectFloor(void __iomem * docptr, int floor)
may not want it */ may not want it */
static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from) static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
{ {
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
if (this->interleave) { if (this->interleave) {
unsigned int ofs = *from & 0x3ff; unsigned int ofs = *from & 0x3ff;
...@@ -458,12 +458,12 @@ static const char im_name[] = "DoCMilPlus_init"; ...@@ -458,12 +458,12 @@ static const char im_name[] = "DoCMilPlus_init";
*/ */
static void DoCMilPlus_init(struct mtd_info *mtd) static void DoCMilPlus_init(struct mtd_info *mtd)
{ {
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
struct DiskOnChip *old = NULL; struct DiskOnChip *old = NULL;
/* We must avoid being called twice for the same device. */ /* We must avoid being called twice for the same device. */
if (docmilpluslist) if (docmilpluslist)
old = (struct DiskOnChip *)docmilpluslist->priv; old = docmilpluslist->priv;
while (old) { while (old) {
if (DoCMilPlus_is_alias(this, old)) { if (DoCMilPlus_is_alias(this, old)) {
...@@ -475,7 +475,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd) ...@@ -475,7 +475,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
return; return;
} }
if (old->nextdoc) if (old->nextdoc)
old = (struct DiskOnChip *)old->nextdoc->priv; old = old->nextdoc->priv;
else else
old = NULL; old = NULL;
} }
...@@ -530,7 +530,7 @@ static int doc_dumpblk(struct mtd_info *mtd, loff_t from) ...@@ -530,7 +530,7 @@ static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
{ {
int i; int i;
loff_t fofs; loff_t fofs;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem * docptr = this->virtadr; void __iomem * docptr = this->virtadr;
struct Nand *mychip = &this->chips[from >> (this->chipshift)]; struct Nand *mychip = &this->chips[from >> (this->chipshift)];
unsigned char *bp, buf[1056]; unsigned char *bp, buf[1056];
...@@ -615,7 +615,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -615,7 +615,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
volatile char dummy; volatile char dummy;
loff_t fofs; loff_t fofs;
unsigned char syndrome[6]; unsigned char syndrome[6];
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem * docptr = this->virtadr; void __iomem * docptr = this->virtadr;
struct Nand *mychip = &this->chips[from >> (this->chipshift)]; struct Nand *mychip = &this->chips[from >> (this->chipshift)];
...@@ -754,7 +754,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -754,7 +754,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
int i, before, ret = 0; int i, before, ret = 0;
loff_t fto; loff_t fto;
volatile char dummy; volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem * docptr = this->virtadr; void __iomem * docptr = this->virtadr;
struct Nand *mychip = &this->chips[to >> (this->chipshift)]; struct Nand *mychip = &this->chips[to >> (this->chipshift)];
...@@ -880,7 +880,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -880,7 +880,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, u_char *buf) size_t *retlen, u_char *buf)
{ {
loff_t fofs, base; loff_t fofs, base;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem * docptr = this->virtadr; void __iomem * docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift]; struct Nand *mychip = &this->chips[ofs >> this->chipshift];
size_t i, size, got, want; size_t i, size, got, want;
...@@ -958,7 +958,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -958,7 +958,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
{ {
volatile char dummy; volatile char dummy;
loff_t fofs, base; loff_t fofs, base;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
void __iomem * docptr = this->virtadr; void __iomem * docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift]; struct Nand *mychip = &this->chips[ofs >> this->chipshift];
size_t i, size, got, want; size_t i, size, got, want;
...@@ -1058,7 +1058,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ...@@ -1058,7 +1058,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
int doc_erase(struct mtd_info *mtd, struct erase_info *instr) int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
{ {
volatile char dummy; volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *this = mtd->priv;
__u32 ofs = instr->addr; __u32 ofs = instr->addr;
__u32 len = instr->len; __u32 len = instr->len;
void __iomem * docptr = this->virtadr; void __iomem * docptr = this->virtadr;
...@@ -1134,7 +1134,7 @@ static void __exit cleanup_doc2001plus(void) ...@@ -1134,7 +1134,7 @@ static void __exit cleanup_doc2001plus(void)
struct DiskOnChip *this; struct DiskOnChip *this;
while ((mtd=docmilpluslist)) { while ((mtd=docmilpluslist)) {
this = (struct DiskOnChip *)mtd->priv; this = mtd->priv;
docmilpluslist = this->nextdoc; docmilpluslist = this->nextdoc;
del_mtd_device(mtd); del_mtd_device(mtd);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
/* (C) 1999 Machine Vision Holdings, Inc. */ /* (C) 1999 Machine Vision Holdings, Inc. */
/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */ /* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
/* $Id: docprobe.c,v 1.43 2004/11/16 18:29:01 dwmw2 Exp $ */ /* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $ */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* $Id: ms02-nv.c,v 1.7 2004/07/29 14:16:45 macro Exp $ * $Id: ms02-nv.c,v 1.8 2005/01/05 18:05:12 dwmw2 Exp $
*/ */
#include <linux/init.h> #include <linux/init.h>
...@@ -59,7 +59,7 @@ static struct mtd_info *root_ms02nv_mtd; ...@@ -59,7 +59,7 @@ static struct mtd_info *root_ms02nv_mtd;
static int ms02nv_read(struct mtd_info *mtd, loff_t from, static int ms02nv_read(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen, u_char *buf) size_t len, size_t *retlen, u_char *buf)
{ {
struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv; struct ms02nv_private *mp = mtd->priv;
if (from + len > mtd->size) if (from + len > mtd->size)
return -EINVAL; return -EINVAL;
...@@ -73,7 +73,7 @@ static int ms02nv_read(struct mtd_info *mtd, loff_t from, ...@@ -73,7 +73,7 @@ static int ms02nv_read(struct mtd_info *mtd, loff_t from,
static int ms02nv_write(struct mtd_info *mtd, loff_t to, static int ms02nv_write(struct mtd_info *mtd, loff_t to,
size_t len, size_t *retlen, const u_char *buf) size_t len, size_t *retlen, const u_char *buf)
{ {
struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv; struct ms02nv_private *mp = mtd->priv;
if (to + len > mtd->size) if (to + len > mtd->size)
return -EINVAL; return -EINVAL;
...@@ -265,7 +265,7 @@ static int __init ms02nv_init_one(ulong addr) ...@@ -265,7 +265,7 @@ static int __init ms02nv_init_one(ulong addr)
static void __exit ms02nv_remove_one(void) static void __exit ms02nv_remove_one(void)
{ {
struct mtd_info *mtd = root_ms02nv_mtd; struct mtd_info *mtd = root_ms02nv_mtd;
struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv; struct ms02nv_private *mp = mtd->priv;
root_ms02nv_mtd = mp->next; root_ms02nv_mtd = mp->next;
......
/* /*
* mtdram - a test mtd device * mtdram - a test mtd device
* $Id: mtdram.c,v 1.34 2004/11/16 18:29:01 dwmw2 Exp $ * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $
* Author: Alexander Larsson <alex@cendio.se> * Author: Alexander Larsson <alex@cendio.se>
* *
* Copyright (c) 1999 Alexander Larsson <alex@cendio.se> * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
...@@ -158,7 +158,7 @@ static int __init init_mtdram(void) ...@@ -158,7 +158,7 @@ static int __init init_mtdram(void)
void *addr; void *addr;
int err; int err;
/* Allocate some memory */ /* Allocate some memory */
mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL); mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
if (!mtd_info) if (!mtd_info)
return -ENOMEM; return -ENOMEM;
...@@ -191,7 +191,7 @@ static int __init init_mtdram(void) ...@@ -191,7 +191,7 @@ static int __init init_mtdram(void)
void *addr; void *addr;
int err; int err;
/* Allocate some memory */ /* Allocate some memory */
mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL); mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
if (!mtd_info) if (!mtd_info)
return -ENOMEM; return -ENOMEM;
......
/** /**
* $Id: phram.c,v 1.11 2005/01/05 18:05:13 dwmw2 Exp $
* *
* $Id: phram.c,v 1.3 2004/11/16 18:29:01 dwmw2 Exp $ * Copyright (c) ???? Jochen Schuble <psionic@psionic.de>
* * Copyright (c) 2003-2004 Jrn Engel <joern@wh.fh-wedel.de>
* Copyright (c) Jochen Schaeuble <psionic@psionic.de>
* 07/2003 rewritten by Joern Engel <joern@wh.fh-wedel.de>
*
* DISCLAIMER: This driver makes use of Rusty's excellent module code,
* so it will not work for 2.4 without changes and it wont work for 2.4
* as a module without major changes. Oh well!
* *
* Usage: * Usage:
* *
...@@ -15,9 +10,12 @@ ...@@ -15,9 +10,12 @@
* phram=<name>,<start>,<len> * phram=<name>,<start>,<len>
* <name> may be up to 63 characters. * <name> may be up to 63 characters.
* <start> and <len> can be octal, decimal or hexadecimal. If followed * <start> and <len> can be octal, decimal or hexadecimal. If followed
* by "k", "M" or "G", the numbers will be interpreted as kilo, mega or * by "ki", "Mi" or "Gi", the numbers will be interpreted as kilo, mega or
* gigabytes. * gigabytes.
* *
* Example:
* phram=swap,64Mi,128Mi phram=test,900Mi,1Mi
*
*/ */
#include <asm/io.h> #include <asm/io.h>
...@@ -31,8 +29,8 @@ ...@@ -31,8 +29,8 @@
#define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args) #define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
struct phram_mtd_list { struct phram_mtd_list {
struct mtd_info mtd;
struct list_head list; struct list_head list;
struct mtd_info *mtdinfo;
}; };
static LIST_HEAD(phram_list); static LIST_HEAD(phram_list);
...@@ -41,7 +39,7 @@ static LIST_HEAD(phram_list); ...@@ -41,7 +39,7 @@ static LIST_HEAD(phram_list);
static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
{ {
u_char *start = (u_char *)mtd->priv; u_char *start = mtd->priv;
if (instr->addr + instr->len > mtd->size) if (instr->addr + instr->len > mtd->size)
return -EINVAL; return -EINVAL;
...@@ -63,7 +61,7 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) ...@@ -63,7 +61,7 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char **mtdbuf) size_t *retlen, u_char **mtdbuf)
{ {
u_char *start = (u_char *)mtd->priv; u_char *start = mtd->priv;
if (from + len > mtd->size) if (from + len > mtd->size)
return -EINVAL; return -EINVAL;
...@@ -80,7 +78,7 @@ static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_ ...@@ -80,7 +78,7 @@ static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_
static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf) size_t *retlen, u_char *buf)
{ {
u_char *start = (u_char *)mtd->priv; u_char *start = mtd->priv;
if (from + len > mtd->size) if (from + len > mtd->size)
return -EINVAL; return -EINVAL;
...@@ -94,7 +92,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -94,7 +92,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf) size_t *retlen, const u_char *buf)
{ {
u_char *start = (u_char *)mtd->priv; u_char *start = mtd->priv;
if (to + len > mtd->size) if (to + len > mtd->size)
return -EINVAL; return -EINVAL;
...@@ -112,9 +110,8 @@ static void unregister_devices(void) ...@@ -112,9 +110,8 @@ static void unregister_devices(void)
struct phram_mtd_list *this; struct phram_mtd_list *this;
list_for_each_entry(this, &phram_list, list) { list_for_each_entry(this, &phram_list, list) {
del_mtd_device(this->mtdinfo); del_mtd_device(&this->mtd);
iounmap(this->mtdinfo->priv); iounmap(this->mtd.priv);
kfree(this->mtdinfo);
kfree(this); kfree(this);
} }
} }
...@@ -128,45 +125,39 @@ static int register_device(char *name, unsigned long start, unsigned long len) ...@@ -128,45 +125,39 @@ static int register_device(char *name, unsigned long start, unsigned long len)
if (!new) if (!new)
goto out0; goto out0;
new->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); memset(new, 0, sizeof(*new));
if (!new->mtdinfo)
goto out1;
memset(new->mtdinfo, 0, sizeof(struct mtd_info));
ret = -EIO; ret = -EIO;
new->mtdinfo->priv = ioremap(start, len); new->mtd.priv = ioremap(start, len);
if (!new->mtdinfo->priv) { if (!new->mtd.priv) {
ERROR("ioremap failed\n"); ERROR("ioremap failed\n");
goto out2; goto out1;
} }
new->mtdinfo->name = name; new->mtd.name = name;
new->mtdinfo->size = len; new->mtd.size = len;
new->mtdinfo->flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE; new->mtd.flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE;
new->mtdinfo->erase = phram_erase; new->mtd.erase = phram_erase;
new->mtdinfo->point = phram_point; new->mtd.point = phram_point;
new->mtdinfo->unpoint = phram_unpoint; new->mtd.unpoint = phram_unpoint;
new->mtdinfo->read = phram_read; new->mtd.read = phram_read;
new->mtdinfo->write = phram_write; new->mtd.write = phram_write;
new->mtdinfo->owner = THIS_MODULE; new->mtd.owner = THIS_MODULE;
new->mtdinfo->type = MTD_RAM; new->mtd.type = MTD_RAM;
new->mtdinfo->erasesize = 0x0; new->mtd.erasesize = 0;
ret = -EAGAIN; ret = -EAGAIN;
if (add_mtd_device(new->mtdinfo)) { if (add_mtd_device(&new->mtd)) {
ERROR("Failed to register new device\n"); ERROR("Failed to register new device\n");
goto out3; goto out2;
} }
list_add_tail(&new->list, &phram_list); list_add_tail(&new->list, &phram_list);
return 0; return 0;
out3:
iounmap(new->mtdinfo->priv);
out2: out2:
kfree(new->mtdinfo); iounmap(new->mtd.priv);
out1: out1:
kfree(new); kfree(new);
out0: out0:
...@@ -184,7 +175,9 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base) ...@@ -184,7 +175,9 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base)
result *= 1024; result *= 1024;
case 'k': case 'k':
result *= 1024; result *= 1024;
endp++; /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
if ((*endp)[1] == 'i')
(*endp) += 2;
} }
return result; return result;
} }
...@@ -235,7 +228,7 @@ static int phram_setup(const char *val, struct kernel_param *kp) ...@@ -235,7 +228,7 @@ static int phram_setup(const char *val, struct kernel_param *kp)
uint32_t len; uint32_t len;
int i, ret; int i, ret;
if (strnlen(val, sizeof(str)) >= sizeof(str)) if (strnlen(val, sizeof(buf)) >= sizeof(buf))
parse_err("parameter too long\n"); parse_err("parameter too long\n");
strcpy(str, val); strcpy(str, val);
...@@ -271,78 +264,11 @@ static int phram_setup(const char *val, struct kernel_param *kp) ...@@ -271,78 +264,11 @@ static int phram_setup(const char *val, struct kernel_param *kp)
} }
module_param_call(phram, phram_setup, NULL, NULL, 000); module_param_call(phram, phram_setup, NULL, NULL, 000);
MODULE_PARM_DESC(phram, "Memory region to map. \"map=<name>,<start><length>\""); MODULE_PARM_DESC(phram,"Memory region to map. \"map=<name>,<start>,<length>\"");
/*
* Just for compatibility with slram, this is horrible and should go someday.
*/
static int __init slram_setup(const char *val, struct kernel_param *kp)
{
char buf[256], *str = buf;
if (!val || !val[0])
parse_err("no arguments to \"slram=\"\n");
if (strnlen(val, sizeof(str)) >= sizeof(str))
parse_err("parameter too long\n");
strcpy(str, val);
while (str) {
char *token[3];
char *name;
uint32_t start;
uint32_t len;
int i, ret;
for (i=0; i<3; i++) {
token[i] = strsep(&str, ",");
if (token[i])
continue;
parse_err("wrong number of arguments to \"slram=\"\n");
}
/* name */
ret = parse_name(&name, token[0]);
if (ret == -ENOMEM)
parse_err("of memory\n");
if (ret == -ENOSPC)
parse_err("too long\n");
if (ret)
return 1;
/* start */
ret = parse_num32(&start, token[1]);
if (ret)
parse_err("illegal start address\n");
/* len */
if (token[2][0] == '+')
ret = parse_num32(&len, token[2] + 1);
else
ret = parse_num32(&len, token[2]);
if (ret)
parse_err("illegal device length\n");
if (token[2][0] != '+') {
if (len < start)
parse_err("end < start\n");
len -= start;
}
register_device(name, start, len);
}
return 1;
}
module_param_call(slram, slram_setup, NULL, NULL, 000);
MODULE_PARM_DESC(slram, "List of memory regions to map. \"map=<name>,<start><length/end>\"");
static int __init init_phram(void) static int __init init_phram(void)
{ {
printk(KERN_ERR "phram loaded\n");
return 0; return 0;
} }
......
/* /*
* $Id: pmc551.c,v 1.29 2004/11/16 18:29:01 dwmw2 Exp $ * $Id: pmc551.c,v 1.30 2005/01/05 18:05:13 dwmw2 Exp $
* *
* PMC551 PCI Mezzanine Ram Device * PMC551 PCI Mezzanine Ram Device
* *
...@@ -113,7 +113,7 @@ static struct mtd_info *pmc551list; ...@@ -113,7 +113,7 @@ static struct mtd_info *pmc551list;
static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr) static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr)
{ {
struct mypriv *priv = (struct mypriv *)mtd->priv; struct mypriv *priv = mtd->priv;
u32 soff_hi, soff_lo; /* start address offset hi/lo */ u32 soff_hi, soff_lo; /* start address offset hi/lo */
u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
unsigned long end; unsigned long end;
...@@ -176,7 +176,7 @@ static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr) ...@@ -176,7 +176,7 @@ static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr)
static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
{ {
struct mypriv *priv = (struct mypriv *)mtd->priv; struct mypriv *priv = mtd->priv;
u32 soff_hi; u32 soff_hi;
u32 soff_lo; u32 soff_lo;
...@@ -217,7 +217,7 @@ static void pmc551_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, siz ...@@ -217,7 +217,7 @@ static void pmc551_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, siz
static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{ {
struct mypriv *priv = (struct mypriv *)mtd->priv; struct mypriv *priv = mtd->priv;
u32 soff_hi, soff_lo; /* start address offset hi/lo */ u32 soff_hi, soff_lo; /* start address offset hi/lo */
u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
unsigned long end; unsigned long end;
...@@ -279,7 +279,7 @@ static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *r ...@@ -279,7 +279,7 @@ static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *r
static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
{ {
struct mypriv *priv = (struct mypriv *)mtd->priv; struct mypriv *priv = mtd->priv;
u32 soff_hi, soff_lo; /* start address offset hi/lo */ u32 soff_hi, soff_lo; /* start address offset hi/lo */
u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
unsigned long end; unsigned long end;
...@@ -820,7 +820,7 @@ static void __exit cleanup_pmc551(void) ...@@ -820,7 +820,7 @@ static void __exit cleanup_pmc551(void)
struct mypriv *priv; struct mypriv *priv;
while((mtd=pmc551list)) { while((mtd=pmc551list)) {
priv = (struct mypriv *)mtd->priv; priv = mtd->priv;
pmc551list = priv->nextpmc551; pmc551list = priv->nextpmc551;
if(priv->start) { if(priv->start) {
......
/*====================================================================== /*======================================================================
$Id: slram.c,v 1.32 2004/11/16 18:29:01 dwmw2 Exp $ $Id: slram.c,v 1.33 2005/01/05 18:05:13 dwmw2 Exp $
This driver provides a method to access memory not used by the kernel 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 itself (i.e. if the kernel commandline mem=xxx is used). To actually
...@@ -106,7 +106,7 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr) ...@@ -106,7 +106,7 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char **mtdbuf) size_t *retlen, u_char **mtdbuf)
{ {
slram_priv_t *priv = (slram_priv_t *)mtd->priv; slram_priv_t *priv = mtd->priv;
*mtdbuf = priv->start + from; *mtdbuf = priv->start + from;
*retlen = len; *retlen = len;
...@@ -120,7 +120,7 @@ static void slram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_ ...@@ -120,7 +120,7 @@ static void slram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_
static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf) size_t *retlen, u_char *buf)
{ {
slram_priv_t *priv = (slram_priv_t *)mtd->priv; slram_priv_t *priv = mtd->priv;
memcpy(buf, priv->start + from, len); memcpy(buf, priv->start + from, len);
...@@ -131,7 +131,7 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -131,7 +131,7 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
static int slram_write(struct mtd_info *mtd, loff_t to, size_t len, static int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf) size_t *retlen, const u_char *buf)
{ {
slram_priv_t *priv = (slram_priv_t *)mtd->priv; slram_priv_t *priv = mtd->priv;
memcpy(priv->start + to, buf, len); memcpy(priv->start + to, buf, len);
...@@ -161,7 +161,7 @@ static int register_device(char *name, unsigned long start, unsigned long length ...@@ -161,7 +161,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
if ((*curmtd)->mtdinfo) { if ((*curmtd)->mtdinfo) {
memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info)); memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
(*curmtd)->mtdinfo->priv = (*curmtd)->mtdinfo->priv =
(void *)kmalloc(sizeof(slram_priv_t), GFP_KERNEL); kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
if (!(*curmtd)->mtdinfo->priv) { if (!(*curmtd)->mtdinfo->priv) {
kfree((*curmtd)->mtdinfo); kfree((*curmtd)->mtdinfo);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A. * Copyright (C) 2000 Netgem S.A.
* *
* $Id: inftlmount.c,v 1.15 2004/11/05 21:55:55 kalev Exp $ * $Id: inftlmount.c,v 1.16 2004/11/22 13:50:53 kalev Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#include <linux/mtd/inftl.h> #include <linux/mtd/inftl.h>
#include <linux/mtd/compatmac.h> #include <linux/mtd/compatmac.h>
char inftlmountrev[]="$Revision: 1.15 $"; char inftlmountrev[]="$Revision: 1.16 $";
/* /*
* find_boot_record: Find the INFTL Media Header and its Spare copy which * find_boot_record: Find the INFTL Media Header and its Spare copy which
...@@ -389,8 +389,6 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block) ...@@ -389,8 +389,6 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
struct erase_info *instr = &inftl->instr; struct erase_info *instr = &inftl->instr;
int physblock; int physblock;
instr->mtd = inftl->mbd.mtd;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p," DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p,"
"block=%d)\n", inftl, block); "block=%d)\n", inftl, block);
...@@ -400,6 +398,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block) ...@@ -400,6 +398,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
_first_? */ _first_? */
/* Use async erase interface, test return code */ /* Use async erase interface, test return code */
instr->mtd = inftl->mbd.mtd;
instr->addr = block * inftl->EraseSize; instr->addr = block * inftl->EraseSize;
instr->len = inftl->mbd.mtd->erasesize; instr->len = inftl->mbd.mtd->erasesize;
/* Erase one physical eraseblock at a time, even though the NAND api /* Erase one physical eraseblock at a time, even though the NAND api
......
# drivers/mtd/maps/Kconfig # drivers/mtd/maps/Kconfig
# $Id: Kconfig,v 1.37 2004/10/20 22:57:18 dwmw2 Exp $ # $Id: Kconfig,v 1.42 2005/01/05 16:59:50 dwmw2 Exp $
menu "Mapping drivers for chip access" menu "Mapping drivers for chip access"
depends on MTD!=n depends on MTD!=n
...@@ -159,7 +159,7 @@ config MTD_VMAX ...@@ -159,7 +159,7 @@ config MTD_VMAX
config MTD_SCx200_DOCFLASH config MTD_SCx200_DOCFLASH
tristate "Flash device mapped with DOCCS on NatSemi SCx200" tristate "Flash device mapped with DOCCS on NatSemi SCx200"
depends on X86 && MTD_CFI depends on X86 && MTD_CFI && MTD_PARTITIONS
help help
Enable support for a flash chip mapped using the DOCCS signal on a Enable support for a flash chip mapped using the DOCCS signal on a
National Semiconductor SCx200 processor. National Semiconductor SCx200 processor.
...@@ -373,9 +373,17 @@ config MTD_ARCTIC ...@@ -373,9 +373,17 @@ config MTD_ARCTIC
Arctic board. If you have one of these boards and would like to Arctic board. If you have one of these boards and would like to
use the flash chips on it, say 'Y'. use the flash chips on it, say 'Y'.
config MTD_WALNUT
tristate "Flash device mapped on IBM 405GP Walnut"
depends on MTD_JEDECPROBE && PPC32 && 40x && 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
use the flash chips on it, say 'Y'.
config MTD_EBONY config MTD_EBONY
tristate "Flash devices mapped on IBM 440GP Ebony" tristate "Flash devices mapped on IBM 440GP Ebony"
depends on MTD_CFI && PPC32 && 44x && EBONY depends on MTD_JEDECPROBE && PPC32 && 44x && EBONY
help help
This enables access routines for the flash chips on the IBM 440GP 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 Ebony board. If you have one of these boards and would like to
...@@ -399,7 +407,7 @@ config MTD_REDWOOD ...@@ -399,7 +407,7 @@ config MTD_REDWOOD
config MTD_CHESTNUT config MTD_CHESTNUT
tristate "CFI Flash devices mapped on IBM 750FX or IBM 750GX Eval Boards" tristate "CFI Flash devices mapped on IBM 750FX or IBM 750GX Eval Boards"
depends on MTD_CFI && PPC32 && CHESTNUT depends on MTD_CFI && PPC32 && CHESTNUT && MTD_PARTITIONS
help help
This enables access routines for the flash chips on the IBM This enables access routines for the flash chips on the IBM
750FX and 750GX Eval Boards. If you have one of these boards and 750FX and 750GX Eval Boards. If you have one of these boards and
...@@ -653,5 +661,11 @@ config MTD_BAST_MAXSIZE ...@@ -653,5 +661,11 @@ config MTD_BAST_MAXSIZE
depends on MTD_BAST depends on MTD_BAST
default "4" default "4"
config MTD_SHARP_SL
bool "ROM maped on Sharp SL Series"
depends on MTD && ARCH_PXA
help
This enables access to the flash chip on the Sharp SL Series of PDAs.
endmenu endmenu
# #
# linux/drivers/maps/Makefile # linux/drivers/maps/Makefile
# #
# $Id: Makefile.common,v 1.19 2004/09/21 14:27:16 bjd Exp $ # $Id: Makefile.common,v 1.23 2005/01/05 17:06:36 dwmw2 Exp $
ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
obj-$(CONFIG_MTD) += map_funcs.o obj-$(CONFIG_MTD) += map_funcs.o
...@@ -54,7 +54,7 @@ obj-$(CONFIG_MTD_EDB7312) += edb7312.o ...@@ -54,7 +54,7 @@ obj-$(CONFIG_MTD_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_IMPA7) += impa7.o obj-$(CONFIG_MTD_IMPA7) += impa7.o
obj-$(CONFIG_MTD_FORTUNET) += fortunet.o obj-$(CONFIG_MTD_FORTUNET) += fortunet.o
obj-$(CONFIG_MTD_REDWOOD) += redwood.o obj-$(CONFIG_MTD_REDWOOD) += redwood.o
obj-$(CONFIG_CHESTNUT) += chestnut.o obj-$(CONFIG_MTD_CHESTNUT) += chestnut.o
obj-$(CONFIG_MTD_UCLINUX) += uclinux.o obj-$(CONFIG_MTD_UCLINUX) += uclinux.o
obj-$(CONFIG_MTD_NETtel) += nettel.o obj-$(CONFIG_MTD_NETtel) += nettel.o
obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
...@@ -62,6 +62,7 @@ obj-$(CONFIG_MTD_EBONY) += ebony.o ...@@ -62,6 +62,7 @@ obj-$(CONFIG_MTD_EBONY) += ebony.o
obj-$(CONFIG_MTD_OCOTEA) += ocotea.o obj-$(CONFIG_MTD_OCOTEA) += ocotea.o
obj-$(CONFIG_MTD_BEECH) += beech-mtd.o obj-$(CONFIG_MTD_BEECH) += beech-mtd.o
obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
obj-$(CONFIG_MTD_WALNUT) += walnut.o
obj-$(CONFIG_MTD_H720X) += h720x-flash.o obj-$(CONFIG_MTD_H720X) += h720x-flash.o
obj-$(CONFIG_MTD_SBC8240) += sbc8240.o obj-$(CONFIG_MTD_SBC8240) += sbc8240.o
obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o
...@@ -70,3 +71,4 @@ obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o ...@@ -70,3 +71,4 @@ obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
obj-$(CONFIG_MTD_IXP2000) += ixp2000.o obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
obj-$(CONFIG_MTD_DMV182) += dmv182.o obj-$(CONFIG_MTD_DMV182) += dmv182.o
obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* amd76xrom.c * amd76xrom.c
* *
* Normal mappings of chips in physical memory * Normal mappings of chips in physical memory
* $Id: amd76xrom.c,v 1.18 2004/11/16 18:29:02 dwmw2 Exp $ * $Id: amd76xrom.c,v 1.19 2004/11/28 09:40:39 dwmw2 Exp $
*/ */
#include <linux/module.h> #include <linux/module.h>
......
/* /*
* drivers/mtd/maps/chestnut.c * drivers/mtd/maps/chestnut.c
* *
* $Id: chestnut.c,v 1.1 2005/01/05 16:59:50 dwmw2 Exp $
*
* Flash map driver for IBM Chestnut (750FXGX Eval) * Flash map driver for IBM Chestnut (750FXGX Eval)
* *
* Chose not to enable 8 bit flash as it contains the firware and board * Chose not to enable 8 bit flash as it contains the firmware and board
* info. Thus only the 32bit flash is supported. * info. Thus only the 32bit flash is supported.
* *
* Author: <source@mvista.com> * Author: <source@mvista.com>
...@@ -85,5 +87,5 @@ module_init(init_chestnut); ...@@ -85,5 +87,5 @@ module_init(init_chestnut);
module_exit(cleanup_chestnut); module_exit(cleanup_chestnut);
MODULE_DESCRIPTION("MTD map and partitions for IBM Chestnut (750fxgx Eval)"); MODULE_DESCRIPTION("MTD map and partitions for IBM Chestnut (750fxgx Eval)");
MODULE_AUTHOR("<mvista.com>"); MODULE_AUTHOR("<source@mvista.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
* *
* $Id: dilnetpc.c,v 1.16 2004/11/04 13:24:14 gleixner Exp $ * $Id: dilnetpc.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
* *
* The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems * 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 * featuring the AMD Elan SC410 processor. There are two variants of this
......
/* /*
* $Id: ebony.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ * $Id: ebony.c,v 1.15 2004/12/09 18:39:54 holindho Exp $
* *
* Mapping for Ebony user flash * Mapping for Ebony user flash
* *
...@@ -103,7 +103,7 @@ int __init init_ebony(void) ...@@ -103,7 +103,7 @@ int __init init_ebony(void)
simple_map_init(&ebony_small_map); simple_map_init(&ebony_small_map);
flash = do_map_probe("map_rom", &ebony_small_map); flash = do_map_probe("jedec_probe", &ebony_small_map);
if (flash) { if (flash) {
flash->owner = THIS_MODULE; flash->owner = THIS_MODULE;
add_mtd_partitions(flash, ebony_small_partitions, add_mtd_partitions(flash, ebony_small_partitions,
...@@ -124,7 +124,7 @@ int __init init_ebony(void) ...@@ -124,7 +124,7 @@ int __init init_ebony(void)
simple_map_init(&ebony_large_map); simple_map_init(&ebony_large_map);
flash = do_map_probe("cfi_probe", &ebony_large_map); flash = do_map_probe("jedec_probe", &ebony_large_map);
if (flash) { if (flash) {
flash->owner = THIS_MODULE; flash->owner = THIS_MODULE;
add_mtd_partitions(flash, ebony_large_partitions, add_mtd_partitions(flash, ebony_large_partitions,
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
$Id: elan-104nc.c,v 1.24 2004/11/16 18:29:02 dwmw2 Exp $ $Id: elan-104nc.c,v 1.25 2004/11/28 09:40:39 dwmw2 Exp $
The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16 The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
mode. This drivers uses the CFI probe and Intel Extended Command Set drivers. mode. This drivers uses the CFI probe and Intel Extended Command Set drivers.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ichxrom.c * ichxrom.c
* *
* Normal mappings of chips in physical memory * Normal mappings of chips in physical memory
* $Id: ichxrom.c,v 1.15 2004/11/16 18:29:02 dwmw2 Exp $ * $Id: ichxrom.c,v 1.16 2004/11/28 09:40:39 dwmw2 Exp $
*/ */
#include <linux/module.h> #include <linux/module.h>
......
/* /*
* $Id: l440gx.c,v 1.16 2004/11/16 18:29:02 dwmw2 Exp $ * $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
* *
* BIOS Flash chip on Intel 440GX board. * BIOS Flash chip on Intel 440GX board.
* *
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
* based on sc520cdp.c by Sysgo Real-Time Solutions GmbH * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
* *
* $Id: netsc520.c,v 1.12 2004/11/04 13:24:15 gleixner Exp $ * $Id: netsc520.c,v 1.13 2004/11/28 09:40:40 dwmw2 Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2001-2002, SnapGear (www.snapgear.com) * (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
* *
* $Id: nettel.c,v 1.8 2004/11/04 13:24:15 gleixner Exp $ * $Id: nettel.c,v 1.10 2005/01/05 17:11:29 dwmw2 Exp $
*/ */
/****************************************************************************/ /****************************************************************************/
...@@ -332,8 +332,8 @@ int __init nettel_init(void) ...@@ -332,8 +332,8 @@ int __init nettel_init(void)
/* Destroy useless AMD MTD mapping */ /* Destroy useless AMD MTD mapping */
amd_mtd = NULL; amd_mtd = NULL;
iounmap((void *) nettel_amd_map.virt); iounmap(nettel_amd_map.virt);
nettel_amd_map.virt = (unsigned long) NULL; nettel_amd_map.virt = NULL;
#else #else
/* Only AMD flash supported */ /* Only AMD flash supported */
return(-ENXIO); return(-ENXIO);
...@@ -357,8 +357,7 @@ int __init nettel_init(void) ...@@ -357,8 +357,7 @@ int __init nettel_init(void)
/* Probe for the the size of the first Intel flash */ /* Probe for the the size of the first Intel flash */
nettel_intel_map.size = maxsize; nettel_intel_map.size = maxsize;
nettel_intel_map.phys = intel0addr; nettel_intel_map.phys = intel0addr;
nettel_intel_map.virt = (unsigned long) nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
ioremap_nocache(intel0addr, maxsize);
if (!nettel_intel_map.virt) { if (!nettel_intel_map.virt) {
printk("SNAPGEAR: failed to ioremap() ROMCS1\n"); printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
return(-EIO); return(-EIO);
...@@ -366,8 +365,8 @@ int __init nettel_init(void) ...@@ -366,8 +365,8 @@ int __init nettel_init(void)
simple_map_init(&nettel_intel_map); simple_map_init(&nettel_intel_map);
intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
if (! intel_mtd) { if (!intel_mtd) {
iounmap((void *) nettel_intel_map.virt); iounmap(nettel_intel_map.virt);
return(-ENXIO); return(-ENXIO);
} }
...@@ -388,11 +387,10 @@ int __init nettel_init(void) ...@@ -388,11 +387,10 @@ int __init nettel_init(void)
/* Delete the old map and probe again to do both chips */ /* Delete the old map and probe again to do both chips */
map_destroy(intel_mtd); map_destroy(intel_mtd);
intel_mtd = NULL; intel_mtd = NULL;
iounmap((void *) nettel_intel_map.virt); iounmap(nettel_intel_map.virt);
nettel_intel_map.size = maxsize; nettel_intel_map.size = maxsize;
nettel_intel_map.virt = (unsigned long) nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
ioremap_nocache(intel0addr, maxsize);
if (!nettel_intel_map.virt) { if (!nettel_intel_map.virt) {
printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n"); printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
return(-EIO); return(-EIO);
...@@ -480,7 +478,7 @@ void __exit nettel_cleanup(void) ...@@ -480,7 +478,7 @@ void __exit nettel_cleanup(void)
map_destroy(intel_mtd); map_destroy(intel_mtd);
} }
if (nettel_intel_map.virt) { if (nettel_intel_map.virt) {
iounmap((void *)nettel_intel_map.virt); iounmap(nettel_intel_map.virt);
nettel_intel_map.virt = 0; nettel_intel_map.virt = 0;
} }
#endif #endif
......
/* /*
* $Id: ocelot.c,v 1.15 2004/11/04 13:24:15 gleixner Exp $ * $Id: ocelot.c,v 1.16 2005/01/05 18:05:13 dwmw2 Exp $
* *
* Flash on Momenco Ocelot * Flash on Momenco Ocelot
*/ */
...@@ -28,7 +28,7 @@ static struct mtd_info *nvram_mtd; ...@@ -28,7 +28,7 @@ static struct mtd_info *nvram_mtd;
static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
{ {
struct map_info *map = (struct map_info *)mtd->priv; struct map_info *map = mtd->priv;
size_t done = 0; 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
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* $Id: pci.c,v 1.8 2004/07/12 22:38:29 dwmw2 Exp $ * $Id: pci.c,v 1.9 2004/11/28 09:40:40 dwmw2 Exp $
* *
* Generic PCI memory map driver. We support the following boards: * Generic PCI memory map driver. We support the following boards:
* - Intel IQ80310 ATU. * - Intel IQ80310 ATU.
......
/* /*
* $Id: physmap.c,v 1.36 2004/11/04 13:24:15 gleixner Exp $ * $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $
* *
* Normal mappings of chips in physical memory * Normal mappings of chips in physical memory
* *
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
$Id: sbc_gxx.c,v 1.32 2004/11/16 18:29:02 dwmw2 Exp $ $Id: sbc_gxx.c,v 1.33 2004/11/28 09:40:40 dwmw2 Exp $
The SBC-MediaGX / SBC-GXx has up to 16 MiB of The SBC-MediaGX / SBC-GXx has up to 16 MiB of
Intel StrataFlash (28F320/28F640) in x8 mode. Intel StrataFlash (28F320/28F640) in x8 mode.
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
* *
* $Id: sc520cdp.c,v 1.18 2004/11/04 13:24:15 gleixner Exp $ * $Id: sc520cdp.c,v 1.21 2004/12/13 10:27:08 dedekind Exp $
* *
* *
* The SC520CDP is an evaluation board for the Elan SC520 processor available * The SC520CDP is an evaluation board for the Elan SC520 processor available
......
/* /*
* MTD map driver for BIOS Flash on Intel SCB2 boards * MTD map driver for BIOS Flash on Intel SCB2 boards
* $Id: scb2_flash.c,v 1.10 2004/11/16 18:29:02 dwmw2 Exp $ * $Id: scb2_flash.c,v 1.11 2004/11/28 09:40:40 dwmw2 Exp $
* Copyright (C) 2002 Sun Microsystems, Inc. * Copyright (C) 2002 Sun Microsystems, Inc.
* Tim Hockin <thockin@sun.com> * Tim Hockin <thockin@sun.com>
* *
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
$Id: scx200_docflash.c,v 1.9 2004/11/16 18:29:02 dwmw2 Exp $ $Id: scx200_docflash.c,v 1.10 2004/11/28 09:40:40 dwmw2 Exp $
National Semiconductor SCx200 flash mapped with DOCCS National Semiconductor SCx200 flash mapped with DOCCS
*/ */
......
/*
* sharpsl-flash.c
*
* Copyright (C) 2001 Lineo Japan, Inc.
* Copyright (C) 2002 SHARP
*
* $Id: sharpsl-flash.c,v 1.2 2004/11/24 20:38:06 rpurdie 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
*
* 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.
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#define WINDOW_ADDR 0x00000000
#define WINDOW_SIZE 0x01000000
#define BANK_WIDTH 2
static struct mtd_info *mymtd;
struct map_info sharpsl_map = {
.name = "sharpsl-flash",
.size = WINDOW_SIZE,
.bankwidth = BANK_WIDTH,
.phys = WINDOW_ADDR
};
static struct mtd_partition sharpsl_partitions[1] = {
{
name: "Filesystem",
size: 0x006d0000,
offset: 0x00120000
}
};
#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
int __init init_sharpsl(void)
{
struct mtd_partition *parts;
int nb_parts = 0;
char *part_type = "static";
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) {
printk("Failed to ioremap\n");
return -EIO;
}
mymtd = do_map_probe("map_rom", &sharpsl_map);
if (!mymtd) {
iounmap(sharpsl_map.virt);
return -ENXIO;
}
mymtd->owner = THIS_MODULE;
parts = sharpsl_partitions;
nb_parts = NB_OF(sharpsl_partitions);
printk(KERN_NOTICE "Using %s partision definition\n", part_type);
add_mtd_partitions(mymtd, parts, nb_parts);
return 0;
}
static void __exit cleanup_sharpsl(void)
{
if (mymtd) {
del_mtd_partitions(mymtd);
map_destroy(mymtd);
}
if (sharpsl_map.virt) {
iounmap(sharpsl_map.virt);
sharpsl_map.virt = 0;
}
}
module_init(init_sharpsl);
module_exit(cleanup_sharpsl);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SHARP (Original: Arnold Christensen <AKC@pel.dk>)");
MODULE_DESCRIPTION("MTD map driver for SHARP SL series");
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* - If you have created your own jffs file system and the bios overwrites * - 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. * it during boot, try disabling Drive A: and B: in the boot order.
* *
* $Id: ts5500_flash.c,v 1.1 2004/09/20 15:33:26 sean Exp $ * $Id: ts5500_flash.c,v 1.2 2004/11/28 09:40:40 dwmw2 Exp $
*/ */
#include <linux/config.h> #include <linux/config.h>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
* *
* $Id: uclinux.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $ * $Id: uclinux.c,v 1.10 2005/01/05 18:05:13 dwmw2 Exp $
*/ */
/****************************************************************************/ /****************************************************************************/
...@@ -47,7 +47,7 @@ struct mtd_partition uclinux_romfs[] = { ...@@ -47,7 +47,7 @@ struct mtd_partition uclinux_romfs[] = {
int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char **mtdbuf) size_t *retlen, u_char **mtdbuf)
{ {
struct map_info *map = (struct map_info *) mtd->priv; struct map_info *map = mtd->priv;
*mtdbuf = (u_char *) (map->virt + ((int) from)); *mtdbuf = (u_char *) (map->virt + ((int) from));
*retlen = len; *retlen = len;
return(0); return(0);
...@@ -81,7 +81,7 @@ int __init uclinux_mtd_init(void) ...@@ -81,7 +81,7 @@ int __init uclinux_mtd_init(void)
mtd = do_map_probe("map_ram", mapp); mtd = do_map_probe("map_ram", mapp);
if (!mtd) { if (!mtd) {
printk("uclinux[mtd]: failed to find a mapping?\n"); printk("uclinux[mtd]: failed to find a mapping?\n");
iounmap((void *) mapp->virt); iounmap(mapp->virt);
return(-ENXIO); return(-ENXIO);
} }
......
/*
* $Id: walnut.c,v 1.2 2004/12/10 12:07:42 holindho 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
* option) any later version.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>
#include <linux/version.h>
#include <asm/io.h>
#include <asm/ibm4xx.h>
#include <platforms/4xx/walnut.h>
/* these should be in platforms/4xx/walnut.h ? */
#define WALNUT_FLASH_ONBD_N(x) (x & 0x02)
#define WALNUT_FLASH_SRAM_SEL(x) (x & 0x01)
#define WALNUT_FLASH_LOW 0xFFF00000
#define WALNUT_FLASH_HIGH 0xFFF80000
#define WALNUT_FLASH_SIZE 0x80000
static struct mtd_info *flash;
static struct map_info walnut_map = {
.name = "Walnut flash",
.size = WALNUT_FLASH_SIZE,
.bankwidth = 1,
};
/* Actually, OpenBIOS is the last 128 KiB of the flash - better
* partitioning could be made */
static struct mtd_partition walnut_partitions[] = {
{
.name = "OpenBIOS",
.offset = 0x0,
.size = WALNUT_FLASH_SIZE,
/*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
}
};
int __init init_walnut(void)
{
u8 fpga_brds1;
void *fpga_brds1_adr;
void *fpga_status_adr;
unsigned long flash_base;
/* this should already be mapped (platform/4xx/walnut.c) */
fpga_status_adr = ioremap(WALNUT_FPGA_BASE, 8);
if (!fpga_status_adr)
return -ENOMEM;
fpga_brds1_adr = fpga_status_adr+5;
fpga_brds1 = readb(fpga_brds1_adr);
/* iounmap(fpga_status_adr); */
if (WALNUT_FLASH_ONBD_N(fpga_brds1)) {
printk("The on-board flash is disabled (U79 sw 5)!");
return -EIO;
}
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);
if (!walnut_map.virt) {
printk("Failed to ioremap flash.\n");
return -EIO;
}
simple_map_init(&walnut_map);
flash = do_map_probe("jedec_probe", &walnut_map);
if (flash) {
flash->owner = THIS_MODULE;
add_mtd_partitions(flash, walnut_partitions,
ARRAY_SIZE(walnut_partitions));
} else {
printk("map probe failed for flash\n");
return -ENXIO;
}
return 0;
}
static void __exit cleanup_walnut(void)
{
if (flash) {
del_mtd_partitions(flash);
map_destroy(flash);
}
if (walnut_map.virt) {
iounmap((void *)walnut_map.virt);
walnut_map.virt = 0;
}
}
module_init(init_walnut);
module_exit(cleanup_walnut);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Heikki Lindholm <holindho@infradead.org>");
MODULE_DESCRIPTION("MTD map and partitions for IBM 405GP Walnut boards");
/* /*
* Direct MTD block device access * Direct MTD block device access
* *
* $Id: mtdblock.c,v 1.65 2004/11/16 18:28:59 dwmw2 Exp $ * $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $
* *
* (C) 2000-2003 Nicolas Pitre <nico@cam.org> * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
...@@ -248,7 +248,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev, ...@@ -248,7 +248,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
unsigned long block, char *buf) unsigned long block, char *buf)
{ {
struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
if (unlikely(!mtdblk->cache_data)) { if (unlikely(!mtdblk->cache_data && mtdblk->cache_size)) {
mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
if (!mtdblk->cache_data) if (!mtdblk->cache_data)
return -EINTR; return -EINTR;
......
/* /*
* $Id: mtdchar.c,v 1.65 2004/09/23 23:45:47 gleixner Exp $ * $Id: mtdchar.c,v 1.66 2005/01/05 18:05:11 dwmw2 Exp $
* *
* Character-device access to raw MTD devices. * Character-device access to raw MTD devices.
* *
...@@ -61,7 +61,7 @@ static inline void mtdchar_devfs_exit(void) ...@@ -61,7 +61,7 @@ static inline void mtdchar_devfs_exit(void)
static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
{ {
struct mtd_info *mtd=(struct mtd_info *)file->private_data; struct mtd_info *mtd = file->private_data;
switch (orig) { switch (orig) {
case 0: case 0:
...@@ -134,7 +134,7 @@ static int mtd_close(struct inode *inode, struct file *file) ...@@ -134,7 +134,7 @@ static int mtd_close(struct inode *inode, struct file *file)
DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
mtd = (struct mtd_info *)file->private_data; mtd = file->private_data;
if (mtd->sync) if (mtd->sync)
mtd->sync(mtd); mtd->sync(mtd);
...@@ -151,7 +151,7 @@ static int mtd_close(struct inode *inode, struct file *file) ...@@ -151,7 +151,7 @@ static int mtd_close(struct inode *inode, struct file *file)
static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
{ {
struct mtd_info *mtd = (struct mtd_info *)file->private_data; struct mtd_info *mtd = file->private_data;
size_t retlen=0; size_t retlen=0;
size_t total_retlen=0; size_t total_retlen=0;
int ret=0; int ret=0;
...@@ -210,7 +210,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t ...@@ -210,7 +210,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
{ {
struct mtd_info *mtd = (struct mtd_info *)file->private_data; struct mtd_info *mtd = file->private_data;
char *kbuf; char *kbuf;
size_t retlen; size_t retlen;
size_t total_retlen=0; size_t total_retlen=0;
...@@ -276,7 +276,7 @@ static void mtdchar_erase_callback (struct erase_info *instr) ...@@ -276,7 +276,7 @@ static void mtdchar_erase_callback (struct erase_info *instr)
static int mtd_ioctl(struct inode *inode, struct file *file, static int mtd_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg) u_int cmd, u_long arg)
{ {
struct mtd_info *mtd = (struct mtd_info *)file->private_data; struct mtd_info *mtd = file->private_data;
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
int ret = 0; int ret = 0;
u_long size; u_long size;
......
# drivers/mtd/nand/Kconfig # drivers/mtd/nand/Kconfig
# $Id: Kconfig,v 1.22 2004/10/05 22:11:46 gleixner Exp $ # $Id: Kconfig,v 1.26 2005/01/05 12:42:24 dwmw2 Exp $
menu "NAND Flash Device Drivers" menu "NAND Flash Device Drivers"
depends on MTD!=n depends on MTD!=n
...@@ -7,6 +7,7 @@ menu "NAND Flash Device Drivers" ...@@ -7,6 +7,7 @@ menu "NAND Flash Device Drivers"
config MTD_NAND config MTD_NAND
tristate "NAND Device Support" tristate "NAND Device Support"
depends on MTD depends on MTD
select MTD_NAND_IDS
help help
This enables support for accessing all type of NAND flash This enables support for accessing all type of NAND flash
devices. For further information see devices. For further information see
...@@ -56,8 +57,6 @@ config MTD_NAND_TOTO ...@@ -56,8 +57,6 @@ config MTD_NAND_TOTO
config MTD_NAND_IDS config MTD_NAND_IDS
tristate tristate
default y if MTD_NAND = y || MTD_DOC2000 = y || MTD_DOC2001 = y || MTD_DOC2001PLUS = y
default m if MTD_NAND = m || MTD_DOC2000 = m || MTD_DOC2001 = m || MTD_DOC2001PLUS = m
config MTD_NAND_TX4925NDFMC config MTD_NAND_TX4925NDFMC
tristate "SmartMedia Card on Toshiba RBTX4925 reference board" tristate "SmartMedia Card on Toshiba RBTX4925 reference board"
...@@ -192,4 +191,17 @@ config MTD_NAND_DISKONCHIP_BBTWRITE ...@@ -192,4 +191,17 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
Even if you leave this disabled, you can enable BBT writes at module Even if you leave this disabled, you can enable BBT writes at module
load time (assuming you build diskonchip as a module) with the module load time (assuming you build diskonchip as a module) with the module
parameter "inftl_bbt_write=1". parameter "inftl_bbt_write=1".
config MTD_NAND_SHARPSL
bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
depends on MTD_NAND && ARCH_PXA
config MTD_NAND_NANDSIM
bool "Support for NAND Flash Simulator"
depends on MTD_NAND && MTD_PARTITIONS
help
The simulator may simulate verious NAND flash chips for the
MTD nand layer.
endmenu endmenu
# #
# linux/drivers/nand/Makefile # linux/drivers/nand/Makefile
# #
# $Id: Makefile.common,v 1.13 2004/09/28 22:04:23 bjd Exp $ # $Id: Makefile.common,v 1.15 2004/11/26 12:28:22 dedekind Exp $
obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o
obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
...@@ -18,5 +18,7 @@ obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o ...@@ -18,5 +18,7 @@ obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
obj-$(CONFIG_MTD_NAND_H1900) += h1910.o obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o
obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
nand-objs = nand_base.o nand_bbt.o nand-objs = nand_base.o nand_bbt.o
This diff is collapsed.
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
* The AG-AND chips have nice features for speed improvement, * The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go. * which are not supported yet. Read / program 4 pages in one go.
* *
* $Id: nand_base.c,v 1.121 2004/10/06 19:53:11 gleixner Exp $ * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -810,7 +810,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa ...@@ -810,7 +810,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
{ {
int i, status; int i, status;
u_char ecc_code[8]; u_char ecc_code[32];
int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
int *oob_config = oobsel->eccpos; int *oob_config = oobsel->eccpos;
int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
...@@ -840,18 +840,8 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa ...@@ -840,18 +840,8 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
} }
this->write_buf(mtd, this->data_poi, mtd->oobblock); this->write_buf(mtd, this->data_poi, mtd->oobblock);
break; break;
default:
/* Hardware ecc 8 byte / 512 byte data */ eccbytes = this->eccbytes;
case NAND_ECC_HW8_512:
eccbytes += 2;
/* Hardware ecc 6 byte / 512 byte data */
case NAND_ECC_HW6_512:
eccbytes += 3;
/* Hardware ecc 3 byte / 256 data */
/* Hardware ecc 3 byte / 512 byte data */
case NAND_ECC_HW3_256:
case NAND_ECC_HW3_512:
eccbytes += 3;
for (; eccsteps; eccsteps--) { for (; eccsteps; eccsteps--) {
/* enable hardware ecc logic for write */ /* enable hardware ecc logic for write */
this->enable_hwecc(mtd, NAND_ECC_WRITE); this->enable_hwecc(mtd, NAND_ECC_WRITE);
...@@ -864,14 +854,9 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa ...@@ -864,14 +854,9 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
* the data bytes (words) */ * the data bytes (words) */
if (this->options & NAND_HWECC_SYNDROME) if (this->options & NAND_HWECC_SYNDROME)
this->write_buf(mtd, ecc_code, eccbytes); this->write_buf(mtd, ecc_code, eccbytes);
datidx += this->eccsize; datidx += this->eccsize;
} }
break; break;
default:
printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
BUG();
} }
/* Write out OOB data */ /* Write out OOB data */
...@@ -1051,7 +1036,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, ...@@ -1051,7 +1036,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
int eccmode, eccsteps; int eccmode, eccsteps;
int *oob_config, datidx; int *oob_config, datidx;
int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
int eccbytes = 3; int eccbytes;
int compareecc = 1; int compareecc = 1;
int oobreadlen; int oobreadlen;
...@@ -1092,19 +1077,9 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, ...@@ -1092,19 +1077,9 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
end = mtd->oobblock; end = mtd->oobblock;
ecc = this->eccsize; ecc = this->eccsize;
switch (eccmode) { eccbytes = this->eccbytes;
case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data */
eccbytes = 6;
break;
case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data */
eccbytes = 8;
break;
case NAND_ECC_NONE:
compareecc = 0;
break;
}
if (this->options & NAND_HWECC_SYNDROME) if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
compareecc = 0; compareecc = 0;
oobreadlen = mtd->oobsize; oobreadlen = mtd->oobsize;
...@@ -1165,10 +1140,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, ...@@ -1165,10 +1140,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
break; break;
case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data */ default:
case NAND_ECC_HW3_512: /* Hardware ECC 3 byte /512 byte data */
case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data */
case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data */
for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
this->enable_hwecc(mtd, NAND_ECC_READ); this->enable_hwecc(mtd, NAND_ECC_READ);
this->read_buf(mtd, &data_poi[datidx], ecc); this->read_buf(mtd, &data_poi[datidx], ecc);
...@@ -1193,10 +1165,6 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, ...@@ -1193,10 +1165,6 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
} }
} }
break; break;
default:
printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
BUG();
} }
/* read oobdata */ /* read oobdata */
...@@ -2433,8 +2401,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips) ...@@ -2433,8 +2401,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
* fallback to software ECC * fallback to software ECC
*/ */
this->eccsize = 256; /* set default eccsize */ this->eccsize = 256; /* set default eccsize */
this->eccbytes = 3;
switch (this->eccmode) { switch (this->eccmode) {
case NAND_ECC_HW12_2048:
if (mtd->oobblock < 2048) {
printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
mtd->oobblock);
this->eccmode = NAND_ECC_SOFT;
this->calculate_ecc = nand_calculate_ecc;
this->correct_data = nand_correct_data;
} else
this->eccsize = 2048;
break;
case NAND_ECC_HW3_512: case NAND_ECC_HW3_512:
case NAND_ECC_HW6_512: case NAND_ECC_HW6_512:
...@@ -2444,15 +2423,12 @@ int nand_scan (struct mtd_info *mtd, int maxchips) ...@@ -2444,15 +2423,12 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
this->eccmode = NAND_ECC_SOFT; this->eccmode = NAND_ECC_SOFT;
this->calculate_ecc = nand_calculate_ecc; this->calculate_ecc = nand_calculate_ecc;
this->correct_data = nand_correct_data; this->correct_data = nand_correct_data;
break;
} else } else
this->eccsize = 512; /* set eccsize to 512 and fall through for function check */ this->eccsize = 512; /* set eccsize to 512 */
break;
case NAND_ECC_HW3_256: case NAND_ECC_HW3_256:
if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
break; break;
printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
BUG();
case NAND_ECC_NONE: case NAND_ECC_NONE:
printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
...@@ -2469,10 +2445,31 @@ int nand_scan (struct mtd_info *mtd, int maxchips) ...@@ -2469,10 +2445,31 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
BUG(); BUG();
} }
/* Check hardware ecc function availability and adjust number of ecc bytes per
* calculation step
*/
switch (this->eccmode) {
case NAND_ECC_HW12_2048:
this->eccbytes += 4;
case NAND_ECC_HW8_512:
this->eccbytes += 2;
case NAND_ECC_HW6_512:
this->eccbytes += 3;
case NAND_ECC_HW3_512:
case NAND_ECC_HW3_256:
if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
break;
printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
BUG();
}
mtd->eccsize = this->eccsize; mtd->eccsize = this->eccsize;
/* Set the number of read / write steps for one page to ensure ECC generation */ /* Set the number of read / write steps for one page to ensure ECC generation */
switch (this->eccmode) { switch (this->eccmode) {
case NAND_ECC_HW12_2048:
this->eccsteps = mtd->oobblock / 2048;
break;
case NAND_ECC_HW3_512: case NAND_ECC_HW3_512:
case NAND_ECC_HW6_512: case NAND_ECC_HW6_512:
case NAND_ECC_HW8_512: case NAND_ECC_HW8_512:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
* *
* $Id: nand_bbt.c,v 1.26 2004/10/05 13:50:20 gleixner Exp $ * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -1001,6 +1001,7 @@ int nand_default_bbt (struct mtd_info *mtd) ...@@ -1001,6 +1001,7 @@ int nand_default_bbt (struct mtd_info *mtd)
return nand_scan_bbt (mtd, &agand_flashbased); return nand_scan_bbt (mtd, &agand_flashbased);
} }
/* Is a flash based bad block table requested ? */ /* Is a flash based bad block table requested ? */
if (this->options & NAND_USE_FLASH_BBT) { if (this->options & NAND_USE_FLASH_BBT) {
/* Use the default pattern descriptors */ /* Use the default pattern descriptors */
...@@ -1008,18 +1009,19 @@ int nand_default_bbt (struct mtd_info *mtd) ...@@ -1008,18 +1009,19 @@ int nand_default_bbt (struct mtd_info *mtd)
this->bbt_td = &bbt_main_descr; this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr; this->bbt_md = &bbt_mirror_descr;
} }
if (mtd->oobblock > 512) if (!this->badblock_pattern) {
return nand_scan_bbt (mtd, &largepage_flashbased); this->badblock_pattern = (mtd->oobblock > 512) ?
else &largepage_flashbased : &smallpage_flashbased;
return nand_scan_bbt (mtd, &smallpage_flashbased); }
} else { } else {
this->bbt_td = NULL; this->bbt_td = NULL;
this->bbt_md = NULL; this->bbt_md = NULL;
if (mtd->oobblock > 512) if (!this->badblock_pattern) {
return nand_scan_bbt (mtd, &largepage_memorybased); this->badblock_pattern = (mtd->oobblock > 512) ?
else &largepage_memorybased : &smallpage_memorybased;
return nand_scan_bbt (mtd, &smallpage_memorybased); }
} }
return nand_scan_bbt (mtd, this->badblock_pattern);
} }
/** /**
......
This diff is collapsed.
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* 28-Sep-2004 BJD Fixed ECC placement for Hardware mode * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode
* 12-Oct-2004 BJD Fixed errors in use of platform data * 12-Oct-2004 BJD Fixed errors in use of platform data
* *
* $Id: s3c2410.c,v 1.5 2004/10/12 10:10:15 bjd Exp $ * $Id: s3c2410.c,v 1.7 2005/01/05 18:05:14 dwmw2 Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -117,12 +117,12 @@ static struct s3c2410_nand_info *s3c2410_nand_mtd_toinfo(struct mtd_info *mtd) ...@@ -117,12 +117,12 @@ static struct s3c2410_nand_info *s3c2410_nand_mtd_toinfo(struct mtd_info *mtd)
static struct s3c2410_nand_info *to_nand_info(struct device *dev) static struct s3c2410_nand_info *to_nand_info(struct device *dev)
{ {
return (struct s3c2410_nand_info *)dev_get_drvdata(dev); return dev_get_drvdata(dev);
} }
static struct s3c2410_platform_nand *to_nand_plat(struct device *dev) static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
{ {
return (struct s3c2410_platform_nand *)dev->platform_data; return dev->platform_data;
} }
/* timing calculations */ /* timing calculations */
...@@ -167,7 +167,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, ...@@ -167,7 +167,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
if (plat != NULL) { if (plat != NULL) {
tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 8); tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 8);
twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
twrph1 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
} else { } else {
/* default timings */ /* default timings */
tacls = 8; tacls = 8;
...@@ -205,7 +205,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) ...@@ -205,7 +205,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
unsigned long cur; unsigned long cur;
nmtd = (struct s3c2410_nand_mtd *)this->priv; nmtd = this->priv;
info = nmtd->info; info = nmtd->info;
cur = readl(info->regs + S3C2410_NFCONF); cur = readl(info->regs + S3C2410_NFCONF);
...@@ -424,14 +424,14 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, ...@@ -424,14 +424,14 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{ {
struct nand_chip *this = (struct nand_chip *)mtd->priv; struct nand_chip *this = mtd->priv;
readsb(this->IO_ADDR_R, buf, len); readsb(this->IO_ADDR_R, buf, len);
} }
static void s3c2410_nand_write_buf(struct mtd_info *mtd, static void s3c2410_nand_write_buf(struct mtd_info *mtd,
const u_char *buf, int len) const u_char *buf, int len)
{ {
struct nand_chip *this = (struct nand_chip *)mtd->priv; struct nand_chip *this = mtd->priv;
writesb(this->IO_ADDR_W, buf, len); writesb(this->IO_ADDR_W, buf, len);
} }
......
/*
* drivers/mtd/nand/sharpsl.c
*
* Copyright (C) 2004 Richard Purdie
*
* $Id: sharpsl.c,v 1.3 2005/01/03 14:53:50 rpurdie Exp $
*
* Based on Sharp's NAND driver sharp_sl.c
*
* 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/genhd.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
static void __iomem *sharpsl_io_base;
static int sharpsl_phys_base = 0x0C000000;
/* register offset */
#define ECCLPLB sharpsl_io_base+0x00 /* line parity 7 - 0 bit */
#define ECCLPUB sharpsl_io_base+0x04 /* line parity 15 - 8 bit */
#define ECCCP sharpsl_io_base+0x08 /* column parity 5 - 0 bit */
#define ECCCNTR sharpsl_io_base+0x0C /* ECC byte counter */
#define ECCCLRR sharpsl_io_base+0x10 /* cleare ECC */
#define FLASHIO sharpsl_io_base+0x14 /* Flash I/O */
#define FLASHCTL sharpsl_io_base+0x18 /* Flash Control */
/* Flash control bit */
#define FLRYBY (1 << 5)
#define FLCE1 (1 << 4)
#define FLWP (1 << 3)
#define FLALE (1 << 2)
#define FLCLE (1 << 1)
#define FLCE0 (1 << 0)
/*
* MTD structure for SharpSL
*/
static struct mtd_info *sharpsl_mtd = NULL;
/*
* Define partitions for flash device
*/
#define DEFAULT_NUM_PARTITIONS 3
static int nr_partitions;
static struct mtd_partition sharpsl_nand_default_partition_info[] = {
{
.name = "System Area",
.offset = 0,
.size = 7 * 1024 * 1024,
},
{
.name = "Root Filesystem",
.offset = 7 * 1024 * 1024,
.size = 30 * 1024 * 1024,
},
{
.name = "Home Filesystem",
.offset = MTDPART_OFS_APPEND ,
.size = MTDPART_SIZ_FULL ,
},
};
/*
* hardware specific access to control-lines
*/
static void
sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
{
switch (cmd) {
case NAND_CTL_SETCLE:
writeb(readb(FLASHCTL) | FLCLE, FLASHCTL);
break;
case NAND_CTL_CLRCLE:
writeb(readb(FLASHCTL) & ~FLCLE, FLASHCTL);
break;
case NAND_CTL_SETALE:
writeb(readb(FLASHCTL) | FLALE, FLASHCTL);
break;
case NAND_CTL_CLRALE:
writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
break;
case NAND_CTL_SETNCE:
writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
break;
case NAND_CTL_CLRNCE:
writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
break;
}
}
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
static struct nand_bbt_descr sharpsl_bbt = {
.options = 0,
.offs = 4,
.len = 2,
.pattern = scan_ff_pattern
};
static int
sharpsl_nand_dev_ready(struct mtd_info* mtd)
{
return !((readb(FLASHCTL) & FLRYBY) == 0);
}
static void
sharpsl_nand_enable_hwecc(struct mtd_info* mtd, int mode)
{
writeb(0 ,ECCCLRR);
}
static int
sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
u_char* ecc_code)
{
ecc_code[0] = ~readb(ECCLPUB);
ecc_code[1] = ~readb(ECCLPLB);
ecc_code[2] = (~readb(ECCCP) << 2) | 0x03;
return readb(ECCCNTR) != 0;
}
#ifdef CONFIG_MTD_PARTITIONS
const char *part_probes[] = { "cmdlinepart", NULL };
#endif
/*
* Main initialization routine
*/
int __init
sharpsl_nand_init(void)
{
struct nand_chip *this;
struct mtd_partition* sharpsl_partition_info;
int err = 0;
/* Allocate memory for MTD device structure and private data */
sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
GFP_KERNEL);
if (!sharpsl_mtd) {
printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
return -ENOMEM;
}
/* map physical adress */
sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
if(!sharpsl_io_base){
printk("ioremap to access Sharp SL NAND chip failed\n");
kfree(sharpsl_mtd);
return -EIO;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&sharpsl_mtd[1]);
/* Initialize structures */
memset((char *) sharpsl_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
sharpsl_mtd->priv = this;
/*
* PXA initialize
*/
writeb(readb(FLASHCTL) | FLWP, FLASHCTL);
/* Set address of NAND IO lines */
this->IO_ADDR_R = FLASHIO;
this->IO_ADDR_W = FLASHIO;
/* Set address of hardware control function */
this->hwcontrol = sharpsl_nand_hwcontrol;
this->dev_ready = sharpsl_nand_dev_ready;
/* 15 us command delay time */
this->chip_delay = 15;
/* set eccmode using hardware ECC */
this->eccmode = NAND_ECC_HW3_256;
this->enable_hwecc = sharpsl_nand_enable_hwecc;
this->calculate_ecc = sharpsl_nand_calculate_ecc;
this->correct_data = nand_correct_data;
this->badblock_pattern = &sharpsl_bbt;
/* Scan to find existence of the device */
err=nand_scan(sharpsl_mtd,1);
if (err) {
iounmap(sharpsl_io_base);
kfree(sharpsl_mtd);
return err;
}
/* Register the partitions */
sharpsl_mtd->name = "sharpsl-nand";
nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
&sharpsl_partition_info, 0);
if (nr_partitions <= 0) {
nr_partitions = DEFAULT_NUM_PARTITIONS;
sharpsl_partition_info = sharpsl_nand_default_partition_info;
if (machine_is_poodle()) {
sharpsl_partition_info[1].size=22 * 1024 * 1024;
} else if (machine_is_corgi() || machine_is_shepherd()) {
sharpsl_partition_info[1].size=25 * 1024 * 1024;
} else if (machine_is_husky()) {
sharpsl_partition_info[1].size=53 * 1024 * 1024;
}
}
if (machine_is_husky()) {
/* Need to use small eraseblock size for backward compatibility */
sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
}
add_mtd_partitions(sharpsl_mtd, sharpsl_partition_info, nr_partitions);
/* Return happy */
return 0;
}
module_init(sharpsl_nand_init);
/*
* Clean up routine
*/
#ifdef MODULE
static void __exit sharpsl_nand_cleanup(void)
{
struct nand_chip *this = (struct nand_chip *) &sharpsl_mtd[1];
/* Release resources, unregister device */
nand_release(sharpsl_mtd);
iounmap(sharpsl_io_base);
/* Free the MTD device structure */
kfree(sharpsl_mtd);
}
module_exit(sharpsl_nand_cleanup);
#endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
MODULE_DESCRIPTION("Device specific logic for NAND flash on Sharp SL-C7xx Series");
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A. * Copyright (C) 2000 Netgem S.A.
* *
* $Id: nftlmount.c,v 1.39 2004/11/05 22:51:41 kalev Exp $ * $Id: nftlmount.c,v 1.40 2004/11/22 14:38:29 kalev Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define SECTORSIZE 512 #define SECTORSIZE 512
char nftlmountrev[]="$Revision: 1.39 $"; char nftlmountrev[]="$Revision: 1.40 $";
/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
* various device information of the NFTL partition and Bad Unit Table. Update * various device information of the NFTL partition and Bad Unit Table. Update
...@@ -302,8 +302,6 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block) ...@@ -302,8 +302,6 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
struct nftl_uci1 uci; struct nftl_uci1 uci;
struct erase_info *instr = &nftl->instr; struct erase_info *instr = &nftl->instr;
instr->mtd = nftl->mbd.mtd;
/* Read the Unit Control Information #1 for Wear-Leveling */ /* Read the Unit Control Information #1 for Wear-Leveling */
if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
8, &retlen, (char *)&uci) < 0) 8, &retlen, (char *)&uci) < 0)
...@@ -320,6 +318,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block) ...@@ -320,6 +318,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
memset(instr, 0, sizeof(struct erase_info)); memset(instr, 0, sizeof(struct erase_info));
/* XXX: use async erase interface, XXX: test return code */ /* XXX: use async erase interface, XXX: test return code */
instr->mtd = nftl->mbd.mtd;
instr->addr = block * nftl->EraseSize; instr->addr = block * nftl->EraseSize;
instr->len = nftl->EraseSize; instr->len = nftl->EraseSize;
MTD_ERASE(nftl->mbd.mtd, instr); MTD_ERASE(nftl->mbd.mtd, instr);
......
/* /*
* $Id: redboot.c,v 1.15 2004/08/10 07:55:16 dwmw2 Exp $ * $Id: redboot.c,v 1.17 2004/11/22 11:33:56 ijc Exp $
* *
* Parse RedBoot-style Flash Image System (FIS) tables and * Parse RedBoot-style Flash Image System (FIS) tables and
* produce a Linux partition array to match. * produce a Linux partition array to match.
...@@ -30,6 +30,9 @@ struct fis_list { ...@@ -30,6 +30,9 @@ struct fis_list {
struct fis_list *next; struct fis_list *next;
}; };
static int directory = CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK;
module_param(directory, int, 0);
static inline int redboot_checksum(struct fis_image_desc *img) static inline int redboot_checksum(struct fis_image_desc *img)
{ {
/* RedBoot doesn't actually write the desc_cksum field yet AFAICT */ /* RedBoot doesn't actually write the desc_cksum field yet AFAICT */
...@@ -50,6 +53,8 @@ static int parse_redboot_partitions(struct mtd_info *master, ...@@ -50,6 +53,8 @@ static int parse_redboot_partitions(struct mtd_info *master,
char *nullname; char *nullname;
int namelen = 0; int namelen = 0;
int nulllen = 0; int nulllen = 0;
int numslots;
unsigned long offset;
#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
static char nullstring[] = "unallocated"; static char nullstring[] = "unallocated";
#endif #endif
...@@ -59,8 +64,15 @@ static int parse_redboot_partitions(struct mtd_info *master, ...@@ -59,8 +64,15 @@ static int parse_redboot_partitions(struct mtd_info *master,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
/* Read the start of the last erase block */ if ( directory < 0 )
ret = master->read(master, master->size - master->erasesize, offset = master->size + directory*master->erasesize;
else
offset = directory*master->erasesize;
printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
master->name, offset);
ret = master->read(master, offset,
master->erasesize, &retlen, (void *)buf); master->erasesize, &retlen, (void *)buf);
if (ret) if (ret)
...@@ -71,12 +83,16 @@ static int parse_redboot_partitions(struct mtd_info *master, ...@@ -71,12 +83,16 @@ static int parse_redboot_partitions(struct mtd_info *master,
goto out; goto out;
} }
/* RedBoot image could appear in any of the first three slots */ numslots = (master->erasesize / sizeof(struct fis_image_desc));
for (i = 0; i < 3; i++) { for (i = 0; i < numslots; i++) {
if (!memcmp(buf[i].name, "RedBoot", 8)) if (buf[i].name[0] == 0xff) {
i = numslots;
break;
}
if (!memcmp(buf[i].name, "FIS directory", 14))
break; break;
} }
if (i == 3) { if (i == numslots) {
/* Didn't find it */ /* Didn't find it */
printk(KERN_NOTICE "No RedBoot partition table detected in %s\n", printk(KERN_NOTICE "No RedBoot partition table detected in %s\n",
master->name); master->name);
...@@ -84,7 +100,7 @@ static int parse_redboot_partitions(struct mtd_info *master, ...@@ -84,7 +100,7 @@ static int parse_redboot_partitions(struct mtd_info *master,
goto out; goto out;
} }
for (i = 0; i < master->erasesize / sizeof(struct fis_image_desc); i++) { for (i = 0; i < numslots; i++) {
struct fis_list *new_fl, **prev; struct fis_list *new_fl, **prev;
if (buf[i].name[0] == 0xff) if (buf[i].name[0] == 0xff)
......
...@@ -1191,6 +1191,15 @@ config JFFS2_FS_NAND ...@@ -1191,6 +1191,15 @@ config JFFS2_FS_NAND
Say 'N' unless you have NAND flash. Say 'N' unless you have NAND flash.
config JFFS2_FS_NOR_ECC
bool "JFFS2 support for ECC'd NOR flash (EXPERIMENTAL)"
depends on JFFS2_FS && EXPERIMENTAL
default n
help
This enables the experimental support for NOR flash with transparent
ECC for JFFS2. This type of flash chip is not common, however it is
available from ST Microelectronics.
config JFFS2_COMPRESSION_OPTIONS config JFFS2_COMPRESSION_OPTIONS
bool "Advanced compression options for JFFS2" bool "Advanced compression options for JFFS2"
depends on JFFS2_FS depends on JFFS2_FS
......
# #
# Makefile for the Linux Journalling Flash File System v2 (JFFS2) # Makefile for the Linux Journalling Flash File System v2 (JFFS2)
# #
# $Id: Makefile.common,v 1.6 2004/07/16 15:17:57 dwmw2 Exp $ # $Id: Makefile.common,v 1.7 2004/11/03 12:57:38 jwboyer Exp $
# #
obj-$(CONFIG_JFFS2_FS) += jffs2.o obj-$(CONFIG_JFFS2_FS) += jffs2.o
...@@ -12,6 +12,7 @@ jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o ...@@ -12,6 +12,7 @@ jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o
jffs2-y += super.o jffs2-y += super.o
jffs2-$(CONFIG_JFFS2_FS_NAND) += wbuf.o jffs2-$(CONFIG_JFFS2_FS_NAND) += wbuf.o
jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o
jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
$Id: README.Locking,v 1.4 2002/03/08 16:20:06 dwmw2 Exp $ $Id: README.Locking,v 1.9 2004/11/20 10:35:40 dwmw2 Exp $
JFFS2 LOCKING DOCUMENTATION JFFS2 LOCKING DOCUMENTATION
--------------------------- ---------------------------
...@@ -80,10 +80,10 @@ per-eraseblock lists of physical jffs2_raw_node_ref structures, and ...@@ -80,10 +80,10 @@ per-eraseblock lists of physical jffs2_raw_node_ref structures, and
(NB) the per-inode list of physical nodes. The latter is a special (NB) the per-inode list of physical nodes. The latter is a special
case - see below. case - see below.
As the MTD API permits erase-completion callback functions to be As the MTD API no longer permits erase-completion callback functions
called from bottom-half (timer) context, and these functions access to be called from bottom-half (timer) context (on the basis that nobody
the data structures protected by this lock, it must be locked with ever actually implemented such a thing), it's now sufficient to use
spin_lock_bh(). a simple spin_lock() rather than spin_lock_bh().
Note that the per-inode list of physical nodes (f->nodes) is a special Note that the per-inode list of physical nodes (f->nodes) is a special
case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in
...@@ -99,8 +99,27 @@ pointer when the garbage collection thread exits. The code to kill the ...@@ -99,8 +99,27 @@ pointer when the garbage collection thread exits. The code to kill the
GC thread locks it, sends the signal, then unlocks it - while the GC GC thread locks it, sends the signal, then unlocks it - while the GC
thread itself locks it, zeroes c->gc_task, then unlocks on the exit path. thread itself locks it, zeroes c->gc_task, then unlocks on the exit path.
node_free_sem
------------- inocache_lock spinlock
----------------------
This spinlock protects the hashed list (c->inocache_list) of the
in-core jffs2_inode_cache objects (each inode in JFFS2 has the
correspondent jffs2_inode_cache object). So, the inocache_lock
has to be locked while walking the c->inocache_list hash buckets.
Note, the f->sem guarantees that the correspondent jffs2_inode_cache
will not be removed. So, it is allowed to access it without locking
the inocache_lock spinlock.
Ordering constraints:
If both erase_completion_lock and inocache_lock are needed, the
c->erase_completion has to be acquired first.
erase_free_sem
--------------
This semaphore is only used by the erase code which frees obsolete This semaphore is only used by the erase code which frees obsolete
node references and the jffs2_garbage_collect_deletion_dirent() node references and the jffs2_garbage_collect_deletion_dirent()
...@@ -114,3 +133,16 @@ the jffs2_raw_node_ref structures in question while the garbage ...@@ -114,3 +133,16 @@ the jffs2_raw_node_ref structures in question while the garbage
collection code is looking at them. collection code is looking at them.
Suggestions for alternative solutions to this problem would be welcomed. Suggestions for alternative solutions to this problem would be welcomed.
wbuf_sem
--------
This read/write semaphore protects against concurrent access to the
write-behind buffer ('wbuf') used for flash chips where we must write
in blocks. It protects both the contents of the wbuf and the metadata
which indicates which flash region (if any) is currently covered by
the buffer.
Ordering constraints:
Lock wbuf_sem last, after the alloc_sem or and f->sem.
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
* *
* Copyright (C) 2001-2003 Red Hat, Inc. * Copyright (C) 2001-2003 Red Hat, Inc.
* *
* Created by David Woodhouse <dwmw2@redhat.com> * Created by David Woodhouse <dwmw2@infradead.org>
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: background.c,v 1.49 2004/07/13 08:56:40 dwmw2 Exp $ * $Id: background.c,v 1.50 2004/11/16 20:36:10 dwmw2 Exp $
* *
*/ */
......
This diff is collapsed.
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
* *
* Copyright (C) 2001-2003 Red Hat, Inc. * Copyright (C) 2001-2003 Red Hat, Inc.
* *
* Created by David Woodhouse <dwmw2@redhat.com> * Created by David Woodhouse <dwmw2@infradead.org>
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: compr_zlib.c,v 1.28 2004/06/23 16:34:40 havasi Exp $ * $Id: compr_zlib.c,v 1.29 2004/11/16 20:36:11 dwmw2 Exp $
* *
*/ */
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
* *
* Copyright (C) 2001-2003 Red Hat, Inc. * Copyright (C) 2001-2003 Red Hat, Inc.
* *
* Created by David Woodhouse <dwmw2@redhat.com> * Created by David Woodhouse <dwmw2@infradead.org>
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: dir.c,v 1.83 2004/10/19 07:48:44 havasi Exp $ * $Id: dir.c,v 1.84 2004/11/16 20:36:11 dwmw2 Exp $
* *
*/ */
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
* *
* Copyright (C) 2001-2003 Red Hat, Inc. * Copyright (C) 2001-2003 Red Hat, Inc.
* *
* Created by David Woodhouse <dwmw2@redhat.com> * Created by David Woodhouse <dwmw2@infradead.org>
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: erase.c,v 1.61 2004/10/20 23:59:49 dwmw2 Exp $ * $Id: erase.c,v 1.66 2004/11/16 20:36:11 dwmw2 Exp $
* *
*/ */
...@@ -43,6 +43,7 @@ void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) ...@@ -43,6 +43,7 @@ void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
jffs2_erase_succeeded(c, jeb); jffs2_erase_succeeded(c, jeb);
return; return;
} }
bad_offset = jeb->offset;
#else /* Linux */ #else /* Linux */
struct erase_info *instr; struct erase_info *instr;
...@@ -386,6 +387,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb ...@@ -386,6 +387,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
jeb->dirty_size = 0; jeb->dirty_size = 0;
jeb->wasted_size = 0; jeb->wasted_size = 0;
} else { } else {
struct kvec vecs[1];
struct jffs2_unknown_node marker = { struct jffs2_unknown_node marker = {
.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
...@@ -394,8 +396,10 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb ...@@ -394,8 +396,10 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4)); marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
/* We only write the header; the rest was noise or padding anyway */ vecs[0].iov_base = (unsigned char *) &marker;
ret = jffs2_flash_write(c, jeb->offset, sizeof(marker), &retlen, (char *)&marker); vecs[0].iov_len = sizeof(marker);
ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
if (ret) { if (ret) {
printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n", printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
jeb->offset, ret); jeb->offset, ret);
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
* *
* Copyright (C) 2001-2003 Red Hat, Inc. * Copyright (C) 2001-2003 Red Hat, Inc.
* *
* Created by David Woodhouse <dwmw2@redhat.com> * Created by David Woodhouse <dwmw2@infradead.org>
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: file.c,v 1.98 2004/03/19 16:41:09 dwmw2 Exp $ * $Id: file.c,v 1.99 2004/11/16 20:36:11 dwmw2 Exp $
* *
*/ */
......
This diff is collapsed.
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
* *
* Copyright (C) 2001-2003 Red Hat, Inc. * Copyright (C) 2001-2003 Red Hat, Inc.
* *
* Created by David Woodhouse <dwmw2@redhat.com> * Created by David Woodhouse <dwmw2@infradead.org>
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: gc.c,v 1.140 2004/11/13 10:59:22 dedekind Exp $ * $Id: gc.c,v 1.144 2004/12/21 11:18:50 dwmw2 Exp $
* *
*/ */
...@@ -103,7 +103,7 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c) ...@@ -103,7 +103,7 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
ret->wasted_size = 0; ret->wasted_size = 0;
} }
D1(jffs2_dump_block_lists(c)); D2(jffs2_dump_block_lists(c));
return ret; return ret;
} }
...@@ -134,7 +134,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) ...@@ -134,7 +134,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
if (c->checked_ino > c->highest_ino) { if (c->checked_ino > c->highest_ino) {
printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
c->unchecked_size); c->unchecked_size);
D1(jffs2_dump_block_lists(c)); D2(jffs2_dump_block_lists(c));
spin_unlock(&c->erase_completion_lock); spin_unlock(&c->erase_completion_lock);
BUG(); BUG();
} }
...@@ -602,7 +602,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, ...@@ -602,7 +602,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset);
jffs2_free_raw_node_ref(nraw); jffs2_free_raw_node_ref(nraw);
} }
if (!retried && (nraw == jffs2_alloc_raw_node_ref())) { if (!retried && (nraw = jffs2_alloc_raw_node_ref())) {
/* Try to reallocate space and retry */ /* Try to reallocate space and retry */
uint32_t dummy; uint32_t dummy;
struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size]; struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment