Skip to content
Snippets Groups Projects
Commit be967b7e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.infradead.org/mtd-2.6

* git://git.infradead.org/mtd-2.6: (199 commits)
  [MTD] NAND: Fix breakage all over the place
  [PATCH] NAND: fix remaining OOB length calculation
  [MTD] NAND Fixup NDFC merge brokeness
  [MTD NAND] S3C2410 driver cleanup
  [MTD NAND] s3c24x0 board: Fix clock handling, ensure proper initialisation.
  [JFFS2] Check CRC32 on dirent and data nodes each time they're read
  [JFFS2] When retiring nextblock, allocate a node_ref for the wasted space
  [JFFS2] Mark XATTR support as experimental, for now
  [JFFS2] Don't trust node headers before the CRC is checked.
  [MTD] Restore MTD_ROM and MTD_RAM types
  [MTD] assume mtd->writesize is 1 for NOR flashes
  [MTD NAND] Fix s3c2410 NAND driver so it at least _looks_ like it compiles
  [MTD] Prepare physmap for 64-bit-resources
  [JFFS2] Fix more breakage caused by janitorial meddling.
  [JFFS2] Remove stray __exit from jffs2_compressors_exit()
  [MTD] Allow alternate JFFS2 mount variant for root filesystem.
  [MTD] Disconnect struct mtd_info from ABI
  [MTD] replace MTD_RAM with MTD_GENERIC_TYPE
  [MTD] replace MTD_ROM with MTD_GENERIC_TYPE
  [MTD] remove a forgotten MTD_XIP
  ...
parents eef11427 7bc3312b
No related merge requests found
Showing
with 341 additions and 576 deletions
......@@ -1843,12 +1843,12 @@ S: linux-scsi@vger.kernel.org
W: http://megaraid.lsilogic.com
S: Maintained
MEMORY TECHNOLOGY DEVICES
MEMORY TECHNOLOGY DEVICES (MTD)
P: David Woodhouse
M: dwmw2@infradead.org
W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org
T: git kernel.org:/pub/scm/linux/kernel/git/tglx/mtd-2.6.git
T: git git://git.infradead.org/mtd-2.6.git
S: Maintained
MICROTEK X6 SCANNER
......
......@@ -78,7 +78,7 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
option.
The option specifies which Flash sectors holds the RedBoot
partition table. A zero or positive value gives an absolete
partition table. A zero or positive value gives an absolute
erase block number. A negative value specifies a number of
sectors before the end of the device.
......@@ -103,7 +103,7 @@ config MTD_CMDLINE_PARTS
bool "Command line partition table parsing"
depends on MTD_PARTITIONS = "y"
---help---
Allow generic configuration of the MTD paritition tables via the kernel
Allow generic configuration of the MTD partition tables via the kernel
command line. Multiple flash resources are supported for hardware where
different kinds of flash memory are available.
......
......@@ -30,7 +30,6 @@ config MTD_JEDECPROBE
config MTD_GEN_PROBE
tristate
select OBSOLETE_INTERMODULE
config MTD_CFI_ADV_OPTIONS
bool "Flash chip driver advanced configuration options"
......
......@@ -3,13 +3,6 @@
#
# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
# *** BIG UGLY NOTE ***
#
# The removal of get_module_symbol() and replacement with
# inter_module_register() et al has introduced a link order dependency
# here where previously there was none. We now have to ensure that
# the CFI command set drivers are linked before gen_probe.o
obj-$(CONFIG_MTD) += chipreg.o
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
obj-$(CONFIG_MTD_CFI) += cfi_probe.o
......
......@@ -97,7 +97,6 @@ struct amd_flash_private {
int interleave;
int numchips;
unsigned long chipshift;
// const char *im_name;
struct flchip chips[0];
};
......@@ -131,12 +130,6 @@ static struct mtd_chip_driver amd_flash_chipdrv = {
.module = THIS_MODULE
};
static const char im_name[] = "amd_flash";
static inline __u32 wide_read(struct map_info *map, __u32 addr)
{
if (map->buswidth == 1) {
......@@ -737,6 +730,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
offset += dev_size;
}
mtd->type = MTD_NORFLASH;
mtd->writesize = 1;
mtd->flags = MTD_CAP_NORFLASH;
mtd->name = map->name;
mtd->erase = amd_flash_erase;
......
This diff is collapsed.
......@@ -236,6 +236,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
mtd->resume = cfi_amdstd_resume;
mtd->flags = MTD_CAP_NORFLASH;
mtd->name = map->name;
mtd->writesize = 1;
if (cfi->cfi_mode==CFI_MODE_CFI){
unsigned char bootloc;
......@@ -326,7 +327,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
return cfi_amdstd_setup(mtd);
}
EXPORT_SYMBOL_GPL(cfi_cmdset_0002);
static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
{
......@@ -1758,25 +1759,6 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
kfree(mtd->eraseregions);
}
static char im_name[]="cfi_cmdset_0002";
static int __init cfi_amdstd_init(void)
{
inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
return 0;
}
static void __exit cfi_amdstd_exit(void)
{
inter_module_unregister(im_name);
}
module_init(cfi_amdstd_init);
module_exit(cfi_amdstd_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");
......@@ -162,6 +162,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
return cfi_staa_setup(map);
}
EXPORT_SYMBOL_GPL(cfi_cmdset_0020);
static struct mtd_info *cfi_staa_setup(struct map_info *map)
{
......@@ -237,9 +238,8 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
mtd->unlock = cfi_staa_unlock;
mtd->suspend = cfi_staa_suspend;
mtd->resume = cfi_staa_resume;
mtd->flags = MTD_CAP_NORFLASH;
mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */
mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE;
mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
map->fldrv = &cfi_staa_chipdrv;
__module_get(THIS_MODULE);
mtd->name = map->name;
......@@ -1410,20 +1410,4 @@ static void cfi_staa_destroy(struct mtd_info *mtd)
kfree(cfi);
}
static char im_name[]="cfi_cmdset_0020";
static int __init cfi_staa_init(void)
{
inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0020);
return 0;
}
static void __exit cfi_staa_exit(void)
{
inter_module_unregister(im_name);
}
module_init(cfi_staa_init);
module_exit(cfi_staa_exit);
MODULE_LICENSE("GPL");
......@@ -349,12 +349,12 @@ static void print_cfi_ident(struct cfi_ident *cfip)
else
printk("No Vpp line\n");
printk("Typical byte/word write timeout: %d s\n", 1<<cfip->WordWriteTimeoutTyp);
printk("Maximum byte/word write timeout: %d s\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
printk("Typical full buffer write timeout: %d s\n", 1<<cfip->BufWriteTimeoutTyp);
printk("Maximum full buffer write timeout: %d s\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
}
else
printk("Full buffer write not supported\n");
......
......@@ -37,8 +37,15 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
if (!mtd)
mtd = check_cmd_set(map, 0); /* Then the secondary */
if (mtd)
if (mtd) {
if (mtd->size > map->size) {
printk(KERN_WARNING "Reducing visibility of %ldKiB chip to %ldKiB\n",
(unsigned long)mtd->size >> 10,
(unsigned long)map->size >> 10);
mtd->size = map->size;
}
return mtd;
}
printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
......@@ -100,7 +107,12 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
* Align bitmap storage size to full byte.
*/
max_chips = map->size >> cfi.chipshift;
mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
if (!max_chips) {
printk(KERN_WARNING "NOR chip too large to fit in mapping. Attempting to cope...\n");
max_chips = 1;
}
mapsize = (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG;
chip_map = kmalloc(mapsize, GFP_KERNEL);
if (!chip_map) {
printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
......@@ -194,25 +206,28 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
{
struct cfi_private *cfi = map->fldrv_priv;
__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
#if defined(CONFIG_MODULES) && defined(HAVE_INTER_MODULE)
char probename[32];
#ifdef CONFIG_MODULES
char probename[16+sizeof(MODULE_SYMBOL_PREFIX)];
cfi_cmdset_fn_t *probe_function;
sprintf(probename, "cfi_cmdset_%4.4X", type);
sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type);
probe_function = inter_module_get_request(probename, probename);
probe_function = __symbol_get(probename);
if (!probe_function) {
request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1);
probe_function = __symbol_get(probename);
}
if (probe_function) {
struct mtd_info *mtd;
mtd = (*probe_function)(map, primary);
/* If it was happy, it'll have increased its own use count */
inter_module_put(probename);
symbol_put_addr(probe_function);
return mtd;
}
#endif
printk(KERN_NOTICE "Support for command set %04X not present\n",
type);
printk(KERN_NOTICE "Support for command set %04X not present\n", type);
return NULL;
}
......@@ -226,12 +241,8 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
return NULL;
switch(type){
/* Urgh. Ifdefs. The version with weak symbols was
* _much_ nicer. Shame it didn't seem to work on
* anything but x86, really.
* But we can't rely in inter_module_get() because
* that'd mean we depend on link order.
*/
/* We need these for the !CONFIG_MODULES case,
because symbol_get() doesn't work there */
#ifdef CONFIG_MTD_CFI_INTELEXT
case 0x0001:
case 0x0003:
......@@ -246,9 +257,9 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
case 0x0020:
return cfi_cmdset_0020(map, primary);
#endif
default:
return cfi_cmdset_unknown(map, primary);
}
return cfi_cmdset_unknown(map, primary);
}
MODULE_LICENSE("GPL");
......
......@@ -70,7 +70,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
mtd->read = mapram_read;
mtd->write = mapram_write;
mtd->sync = mapram_nop;
mtd->flags = MTD_CAP_RAM | MTD_VOLATILE;
mtd->flags = MTD_CAP_RAM;
mtd->erasesize = PAGE_SIZE;
while(mtd->size & (mtd->erasesize - 1))
......
......@@ -46,9 +46,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
mtd->write = maprom_write;
mtd->sync = maprom_nop;
mtd->flags = MTD_CAP_ROM;
mtd->erasesize = 131072;
while(mtd->size & (mtd->erasesize - 1))
mtd->erasesize >>= 1;
mtd->erasesize = map->size;
__module_get(THIS_MODULE);
return mtd;
......
......@@ -140,6 +140,7 @@ static struct mtd_info *sharp_probe(struct map_info *map)
mtd->suspend = sharp_suspend;
mtd->resume = sharp_resume;
mtd->flags = MTD_CAP_NORFLASH;
mtd->writesize = 1;
mtd->name = map->name;
memset(sharp, 0, sizeof(*sharp));
......
......@@ -47,6 +47,11 @@ config MTD_MS02NV
accelerator. Say Y here if you have a DECstation 5000/2x0 or a
DECsystem 5900 equipped with such a module.
If you want to compile this driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module will
be called ms02-nv.o.
config MTD_DATAFLASH
tristate "Support for AT45xxx DataFlash"
depends on MTD && SPI_MASTER && EXPERIMENTAL
......@@ -209,7 +214,6 @@ config MTD_DOC2001PLUS
config MTD_DOCPROBE
tristate
select MTD_DOCECC
select OBSOLETE_INTERMODULE
config MTD_DOCECC
tristate
......
......@@ -3,13 +3,6 @@
#
# $Id: Makefile.common,v 1.7 2004/12/22 17:51:15 joern Exp $
# *** BIG UGLY NOTE ***
#
# The removal of get_module_symbol() and replacement with
# inter_module_register() et al has introduced a link order dependency
# here where previously there was none. We now have to ensure that
# doc200[01].o are linked before docprobe.o
obj-$(CONFIG_MTD_DOC2000) += doc2000.o
obj-$(CONFIG_MTD_DOC2001) += doc2001.o
obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o
......
......@@ -4,7 +4,7 @@
* block2mtd.c - create an mtd from a block device
*
* Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk>
* Copyright (C) 2004,2005 Jrn Engel <joern@wh.fh-wedel.de>
* Copyright (C) 2004-2006 Jörn Engel <joern@wh.fh-wedel.de>
*
* Licence: GPL
*/
......@@ -331,7 +331,6 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
dev->mtd.writev = default_mtd_writev;
dev->mtd.sync = block2mtd_sync;
dev->mtd.read = block2mtd_read;
dev->mtd.readv = default_mtd_readv;
dev->mtd.priv = dev;
dev->mtd.owner = THIS_MODULE;
......@@ -351,6 +350,12 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
}
/* This function works similar to reguler strtoul. In addition, it
* allows some suffixes for a more human-readable number format:
* ki, Ki, kiB, KiB - multiply result with 1024
* Mi, MiB - multiply result with 1024^2
* Gi, GiB - multiply result with 1024^3
*/
static int ustrtoul(const char *cp, char **endp, unsigned int base)
{
unsigned long result = simple_strtoul(cp, endp, base);
......@@ -359,11 +364,16 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base)
result *= 1024;
case 'M':
result *= 1024;
case 'K':
case 'k':
result *= 1024;
/* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
if ((*endp)[1] == 'i')
(*endp) += 2;
if ((*endp)[1] == 'i') {
if ((*endp)[2] == 'B')
(*endp) += 3;
else
(*endp) += 2;
}
}
return result;
}
......@@ -418,7 +428,8 @@ static inline void kill_final_newline(char *str)
static int block2mtd_setup(const char *val, struct kernel_param *kp)
{
char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */
char buf[80+12]; /* 80 for device, 12 for erase size */
char *str = buf;
char *token[2];
char *name;
size_t erase_size = PAGE_SIZE;
......@@ -430,7 +441,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
strcpy(str, val);
kill_final_newline(str);
for (i=0; i<2; i++)
for (i = 0; i < 2; i++)
token[i] = strsep(&str, ",");
if (str)
......@@ -449,8 +460,10 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
if (token[1]) {
ret = parse_num(&erase_size, token[1]);
if (ret)
if (ret) {
kfree(name);
parse_err("illegal erase size");
}
}
add_device(name, erase_size);
......
......@@ -59,13 +59,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen,
u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, u_char *buf);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, const u_char *buf);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops);
static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, const u_char *buf);
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
......@@ -517,16 +514,9 @@ static int DoC2k_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
return retval;
}
static const char im_name[] = "DoC2k_init";
/* This routine is made available to other mtd code via
* inter_module_register. It must only be accessed through
* inter_module_get which will bump the use count of this module. The
* addresses passed back in mtd are valid as long as the use count of
* this module is non-zero, i.e. between inter_module_get and
* inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
*/
static void DoC2k_init(struct mtd_info *mtd)
/* This routine is found from the docprobe code by symbol_get(),
* which will bump the use count of this module. */
void DoC2k_init(struct mtd_info *mtd)
{
struct DiskOnChip *this = mtd->priv;
struct DiskOnChip *old = NULL;
......@@ -586,7 +576,7 @@ static void DoC2k_init(struct mtd_info *mtd)
mtd->ecctype = MTD_ECC_RS_DiskOnChip;
mtd->size = 0;
mtd->erasesize = 0;
mtd->oobblock = 512;
mtd->writesize = 512;
mtd->oobsize = 16;
mtd->owner = THIS_MODULE;
mtd->erase = doc_erase;
......@@ -594,9 +584,6 @@ static void DoC2k_init(struct mtd_info *mtd)
mtd->unpoint = NULL;
mtd->read = doc_read;
mtd->write = doc_write;
mtd->read_ecc = doc_read_ecc;
mtd->write_ecc = doc_write_ecc;
mtd->writev_ecc = doc_writev_ecc;
mtd->read_oob = doc_read_oob;
mtd->write_oob = doc_write_oob;
mtd->sync = NULL;
......@@ -623,6 +610,7 @@ static void DoC2k_init(struct mtd_info *mtd)
return;
}
}
EXPORT_SYMBOL_GPL(DoC2k_init);
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t * retlen, u_char * buf)
......@@ -971,72 +959,18 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
return 0;
}
static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen,
u_char *eccbuf, struct nand_oobinfo *oobsel)
{
static char static_buf[512];
static DEFINE_MUTEX(writev_buf_mutex);
size_t totretlen = 0;
size_t thisvecofs = 0;
int ret= 0;
mutex_lock(&writev_buf_mutex);
while(count) {
size_t thislen, thisretlen;
unsigned char *buf;
buf = vecs->iov_base + thisvecofs;
thislen = vecs->iov_len - thisvecofs;
if (thislen >= 512) {
thislen = thislen & ~(512-1);
thisvecofs += thislen;
} else {
/* Not enough to fill a page. Copy into buf */
memcpy(static_buf, buf, thislen);
buf = &static_buf[thislen];
while(count && thislen < 512) {
vecs++;
count--;
thisvecofs = min((512-thislen), vecs->iov_len);
memcpy(buf, vecs->iov_base, thisvecofs);
thislen += thisvecofs;
buf += thisvecofs;
}
buf = static_buf;
}
if (count && thisvecofs == vecs->iov_len) {
thisvecofs = 0;
vecs++;
count--;
}
ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);
totretlen += thisretlen;
if (ret || thisretlen != thislen)
break;
to += thislen;
}
mutex_unlock(&writev_buf_mutex);
*retlen = totretlen;
return ret;
}
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t * retlen, u_char * buf)
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops)
{
struct DiskOnChip *this = mtd->priv;
int len256 = 0, ret;
struct Nand *mychip;
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
ofs += ops->ooboffs;
mutex_lock(&this->lock);
......@@ -1077,7 +1011,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
DoC_ReadBuf(this, &buf[len256], len - len256);
*retlen = len;
ops->retlen = len;
/* Reading the full OOB data drops us off of the end of the page,
* causing the flash device to go into busy mode, so we need
* to wait until ready 11.4.1 and Toshiba TC58256FT docs */
......@@ -1192,17 +1126,20 @@ 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,
size_t * retlen, const u_char * buf)
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops)
{
struct DiskOnChip *this = mtd->priv;
int ret;
struct DiskOnChip *this = mtd->priv;
int ret;
mutex_lock(&this->lock);
ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf);
BUG_ON(ops->mode != MTD_OOB_PLACE);
mutex_lock(&this->lock);
ret = doc_write_oob_nolock(mtd, ofs + ops->ooboffs, ops->len,
&ops->retlen, ops->oobbuf);
mutex_unlock(&this->lock);
return ret;
mutex_unlock(&this->lock);
return ret;
}
static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
......@@ -1277,12 +1214,6 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
*
****************************************************************************/
static int __init init_doc2000(void)
{
inter_module_register(im_name, THIS_MODULE, &DoC2k_init);
return 0;
}
static void __exit cleanup_doc2000(void)
{
struct mtd_info *mtd;
......@@ -1298,11 +1229,9 @@ static void __exit cleanup_doc2000(void)
kfree(this->chips);
kfree(mtd);
}
inter_module_unregister(im_name);
}
module_exit(cleanup_doc2000);
module_init(init_doc2000);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
......
......@@ -43,10 +43,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf, u_char *eccbuf,
struct nand_oobinfo *oobsel);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, u_char *buf);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, const u_char *buf);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops);
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
static struct mtd_info *docmillist = NULL;
......@@ -324,16 +324,9 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
return retval;
}
static const char im_name[] = "DoCMil_init";
/* This routine is made available to other mtd code via
* inter_module_register. It must only be accessed through
* inter_module_get which will bump the use count of this module. The
* addresses passed back in mtd are valid as long as the use count of
* this module is non-zero, i.e. between inter_module_get and
* inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
*/
static void DoCMil_init(struct mtd_info *mtd)
/* This routine is found from the docprobe code by symbol_get(),
* which will bump the use count of this module. */
void DoCMil_init(struct mtd_info *mtd)
{
struct DiskOnChip *this = mtd->priv;
struct DiskOnChip *old = NULL;
......@@ -368,7 +361,7 @@ static void DoCMil_init(struct mtd_info *mtd)
/* FIXME: erase size is not always 8KiB */
mtd->erasesize = 0x2000;
mtd->oobblock = 512;
mtd->writesize = 512;
mtd->oobsize = 16;
mtd->owner = THIS_MODULE;
mtd->erase = doc_erase;
......@@ -376,8 +369,6 @@ static void DoCMil_init(struct mtd_info *mtd)
mtd->unpoint = NULL;
mtd->read = doc_read;
mtd->write = doc_write;
mtd->read_ecc = doc_read_ecc;
mtd->write_ecc = doc_write_ecc;
mtd->read_oob = doc_read_oob;
mtd->write_oob = doc_write_oob;
mtd->sync = NULL;
......@@ -401,6 +392,7 @@ static void DoCMil_init(struct mtd_info *mtd)
return;
}
}
EXPORT_SYMBOL_GPL(DoCMil_init);
static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
......@@ -670,8 +662,8 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
return ret;
}
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, u_char *buf)
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops)
{
#ifndef USE_MEMCPY
int i;
......@@ -680,6 +672,12 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
struct DiskOnChip *this = mtd->priv;
void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift];
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
ofs += ops->ooboffs;
/* Find the chip which is to be used and select it */
if (this->curfloor != mychip->floor) {
......@@ -716,13 +714,13 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
#endif
buf[len - 1] = ReadDOC(docptr, LastDataRead);
*retlen = len;
ops->retlen = len;
return 0;
}
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, const u_char *buf)
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops)
{
#ifndef USE_MEMCPY
int i;
......@@ -732,6 +730,12 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
struct DiskOnChip *this = mtd->priv;
void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift];
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
ofs += ops->ooboffs;
/* Find the chip which is to be used and select it */
if (this->curfloor != mychip->floor) {
......@@ -783,12 +787,12 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
printk("Error programming oob data\n");
/* FIXME: implement Bad Block Replacement (in nftl.c ??) */
*retlen = 0;
ops->retlen = 0;
ret = -EIO;
}
dummy = ReadDOC(docptr, LastDataRead);
*retlen = len;
ops->retlen = len;
return ret;
}
......@@ -856,12 +860,6 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
*
****************************************************************************/
static int __init init_doc2001(void)
{
inter_module_register(im_name, THIS_MODULE, &DoCMil_init);
return 0;
}
static void __exit cleanup_doc2001(void)
{
struct mtd_info *mtd;
......@@ -877,11 +875,9 @@ static void __exit cleanup_doc2001(void)
kfree(this->chips);
kfree(mtd);
}
inter_module_unregister(im_name);
}
module_exit(cleanup_doc2001);
module_init(init_doc2001);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
......
......@@ -47,10 +47,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf, u_char *eccbuf,
struct nand_oobinfo *oobsel);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, u_char *buf);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, const u_char *buf);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops);
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
static struct mtd_info *docmilpluslist = NULL;
......@@ -447,16 +447,9 @@ static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
return retval;
}
static const char im_name[] = "DoCMilPlus_init";
/* This routine is made available to other mtd code via
* inter_module_register. It must only be accessed through
* inter_module_get which will bump the use count of this module. The
* addresses passed back in mtd are valid as long as the use count of
* this module is non-zero, i.e. between inter_module_get and
* inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
*/
static void DoCMilPlus_init(struct mtd_info *mtd)
/* This routine is found from the docprobe code by symbol_get(),
* which will bump the use count of this module. */
void DoCMilPlus_init(struct mtd_info *mtd)
{
struct DiskOnChip *this = mtd->priv;
struct DiskOnChip *old = NULL;
......@@ -490,7 +483,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
mtd->size = 0;
mtd->erasesize = 0;
mtd->oobblock = 512;
mtd->writesize = 512;
mtd->oobsize = 16;
mtd->owner = THIS_MODULE;
mtd->erase = doc_erase;
......@@ -498,8 +491,6 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
mtd->unpoint = NULL;
mtd->read = doc_read;
mtd->write = doc_write;
mtd->read_ecc = doc_read_ecc;
mtd->write_ecc = doc_write_ecc;
mtd->read_oob = doc_read_oob;
mtd->write_oob = doc_write_oob;
mtd->sync = NULL;
......@@ -524,6 +515,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
return;
}
}
EXPORT_SYMBOL_GPL(DoCMilPlus_init);
#if 0
static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
......@@ -876,14 +868,20 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
return ret;
}
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, u_char *buf)
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops)
{
loff_t fofs, base;
struct DiskOnChip *this = mtd->priv;
void __iomem * docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift];
size_t i, size, got, want;
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
ofs += ops->ooboffs;
DoC_CheckASIC(docptr);
......@@ -949,12 +947,12 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
/* Disable flash internally */
WriteDOC(0, docptr, Mplus_FlashSelect);
*retlen = len;
ops->retlen = len;
return 0;
}
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t *retlen, const u_char *buf)
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
struct mtd_oob_ops *ops)
{
volatile char dummy;
loff_t fofs, base;
......@@ -963,6 +961,12 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
struct Nand *mychip = &this->chips[ofs >> this->chipshift];
size_t i, size, got, want;
int ret = 0;
uint8_t *buf = ops->oobbuf;
size_t len = ops->len;
BUG_ON(ops->mode != MTD_OOB_PLACE);
ofs += ops->ooboffs;
DoC_CheckASIC(docptr);
......@@ -1038,7 +1042,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
printk("MTD: Error 0x%x programming oob at 0x%x\n",
dummy, (int)ofs);
/* FIXME: implement Bad Block Replacement */
*retlen = 0;
ops->retlen = 0;
ret = -EIO;
}
dummy = ReadDOC(docptr, Mplus_LastDataRead);
......@@ -1051,7 +1055,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
/* Disable flash internally */
WriteDOC(0, docptr, Mplus_FlashSelect);
*retlen = len;
ops->retlen = len;
return ret;
}
......@@ -1122,12 +1126,6 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
*
****************************************************************************/
static int __init init_doc2001plus(void)
{
inter_module_register(im_name, THIS_MODULE, &DoCMilPlus_init);
return 0;
}
static void __exit cleanup_doc2001plus(void)
{
struct mtd_info *mtd;
......@@ -1143,11 +1141,9 @@ static void __exit cleanup_doc2001plus(void)
kfree(this->chips);
kfree(mtd);
}
inter_module_unregister(im_name);
}
module_exit(cleanup_doc2001plus);
module_init(init_doc2001plus);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");
......
......@@ -231,6 +231,10 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
static int docfound;
extern void DoC2k_init(struct mtd_info *);
extern void DoCMil_init(struct mtd_info *);
extern void DoCMilPlus_init(struct mtd_info *);
static void __init DoC_Probe(unsigned long physadr)
{
void __iomem *docptr;
......@@ -239,8 +243,6 @@ static void __init DoC_Probe(unsigned long physadr)
int ChipID;
char namebuf[15];
char *name = namebuf;
char *im_funcname = NULL;
char *im_modname = NULL;
void (*initroutine)(struct mtd_info *) = NULL;
docptr = ioremap(physadr, DOC_IOREMAP_LEN);
......@@ -278,41 +280,33 @@ static void __init DoC_Probe(unsigned long physadr)
switch(ChipID) {
case DOC_ChipID_Doc2kTSOP:
name="2000 TSOP";
im_funcname = "DoC2k_init";
im_modname = "doc2000";
initroutine = symbol_request(DoC2k_init);
break;
case DOC_ChipID_Doc2k:
name="2000";
im_funcname = "DoC2k_init";
im_modname = "doc2000";
initroutine = symbol_request(DoC2k_init);
break;
case DOC_ChipID_DocMil:
name="Millennium";
#ifdef DOC_SINGLE_DRIVER
im_funcname = "DoC2k_init";
im_modname = "doc2000";
initroutine = symbol_request(DoC2k_init);
#else
im_funcname = "DoCMil_init";
im_modname = "doc2001";
initroutine = symbol_request(DoCMil_init);
#endif /* DOC_SINGLE_DRIVER */
break;
case DOC_ChipID_DocMilPlus16:
case DOC_ChipID_DocMilPlus32:
name="MillenniumPlus";
im_funcname = "DoCMilPlus_init";
im_modname = "doc2001plus";
initroutine = symbol_request(DoCMilPlus_init);
break;
}
if (im_funcname)
initroutine = inter_module_get_request(im_funcname, im_modname);
if (initroutine) {
(*initroutine)(mtd);
inter_module_put(im_funcname);
symbol_put_addr(initroutine);
return;
}
printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment