* [patch] linux 2.4: DEC MS02-NV NVRAM module support
@ 2002-03-28 13:26 Maciej W. Rozycki
2002-03-30 8:19 ` Ralf Baechle
0 siblings, 1 reply; 2+ messages in thread
From: Maciej W. Rozycki @ 2002-03-28 13:26 UTC (permalink / raw)
To: David Woodhouse, Ralf Baechle, Harald Koerfgen; +Cc: linux-mips, linux-mips
Hello,
The patch adds support for the DEC MS02-type lithium battery backed-up
NVRAM board. The board provides 1MB (architecturally up to 4MB) of fast
SRAM originally meant as a PrestoServe NFS accelerator for the MIPS-based
DECstations.
The code works fine for me since its creation back in August. It was not
tested by anyone else -- after announcing the code at the "linux-mips"
list last year I've read from two volunteers but they did not come back
with results ever.
I believe it's suitable for inclusion in the official kernel. The patch
applies both to 2.4.19-pre4 and to the current CVS tree at oss.sgi.com.
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
patch-mips-2.4.18-20020327-ms02-nv-69
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/Documentation/Configure.help linux-mips-2.4.18-20020327/Documentation/Configure.help
--- linux-mips-2.4.18-20020327.macro/Documentation/Configure.help 2002-02-27 05:27:43.000000000 +0000
+++ linux-mips-2.4.18-20020327/Documentation/Configure.help 2002-03-28 09:30:03.000000000 +0000
@@ -12495,6 +12495,18 @@ CONFIG_MTD_SLRAM
you can still use it for storage or swap by using this driver to
present it to the system as a Memory Technology Device.
+DEC MS02-NV NVRAM module support
+CONFIG_MTD_MS02NV
+ This is a MTD driver for the DEC's MS02-type battery backed-up NVRAM
+ module. The module was originally meant as an NFS 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 Documentation/modules.txt. The module will be
+ called ms02-nv.o.
+
Debugging RAM test driver
CONFIG_MTD_MTDRAM
This enables a test MTD device driver which uses vmalloc() to
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Config.in linux-mips-2.4.18-20020327/drivers/mtd/devices/Config.in
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Config.in 2001-11-06 05:27:13.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/Config.in 2002-03-28 09:29:07.000000000 +0000
@@ -10,6 +10,7 @@ if [ "$CONFIG_MTD_PMC551" = "y" -o "$CO
bool ' PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
bool ' PMC551 Debugging' CONFIG_MTD_PMC551_DEBUG
fi
+dep_tristate ' DEC MS02-NV NVRAM module support' CONFIG_MTD_MS02NV $CONFIG_MTD $CONFIG_DECSTATION
dep_tristate ' Uncached system RAM' CONFIG_MTD_SLRAM $CONFIG_MTD
if [ "$CONFIG_SA1100_LART" = "y" ]; then
dep_tristate ' 28F160xx flash driver for LART' CONFIG_MTD_LART $CONFIG_MTD
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Makefile linux-mips-2.4.18-20020327/drivers/mtd/devices/Makefile
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/Makefile 2001-11-06 05:27:13.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/Makefile 2002-03-28 09:29:07.000000000 +0000
@@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_DOC2001) += doc2001.o
obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o docecc.o
obj-$(CONFIG_MTD_SLRAM) += slram.o
obj-$(CONFIG_MTD_PMC551) += pmc551.o
+obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o
obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
obj-$(CONFIG_MTD_LART) += lart.o
obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.c linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.c
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.c 1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.c 2002-03-28 09:35:33.000000000 +0000
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2001 Maciej W. Rozycki
+ *
+ * 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/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn03.h>
+#include <asm/io.h>
+#include <asm/paccess.h>
+
+#include "ms02-nv.h"
+
+
+static char version[] __initdata =
+ "ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n";
+
+MODULE_AUTHOR("Maciej W. Rozycki <macro@ds2.pg.gda.pl>");
+MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Addresses we probe for an MS02-NV at. Modules may be located
+ * at any 8MB boundary within a 0MB up to 112MB range or at any 32MB
+ * boundary within a 0MB up to 448MB range. We don't support a module
+ * at 0MB, though.
+ */
+static ulong ms02nv_addrs[] __initdata = {
+ 0x07000000, 0x06800000, 0x06000000, 0x05800000, 0x05000000,
+ 0x04800000, 0x04000000, 0x03800000, 0x03000000, 0x02800000,
+ 0x02000000, 0x01800000, 0x01000000, 0x00800000
+};
+
+static const char ms02nv_name[] = "DEC MS02-NV NVRAM";
+static const char ms02nv_res_diag_ram[] = "Diagnostic RAM";
+static const char ms02nv_res_user_ram[] = "General-purpose RAM";
+static const char ms02nv_res_csr[] = "Control and status register";
+
+static struct mtd_info *root_ms02nv_mtd;
+
+
+static int ms02nv_read(struct mtd_info *mtd, loff_t from,
+ size_t len, size_t *retlen, u_char *buf)
+{
+ struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+ if (from + len > mtd->size)
+ return -EINVAL;
+
+ memcpy(buf, mp->uaddr + from, len);
+ *retlen = len;
+
+ return 0;
+}
+
+static int ms02nv_write(struct mtd_info *mtd, loff_t to,
+ size_t len, size_t *retlen, const u_char *buf)
+{
+ struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+ if (to + len > mtd->size)
+ return -EINVAL;
+
+ memcpy(mp->uaddr + to, buf, len);
+ *retlen = len;
+
+ return 0;
+}
+
+
+static inline uint ms02nv_probe_one(ulong addr)
+{
+ ms02nv_uint *ms02nv_diagp;
+ ms02nv_uint *ms02nv_magicp;
+ uint ms02nv_diag;
+ uint ms02nv_magic;
+ size_t size;
+
+ int err;
+
+ /*
+ * The firmware writes MS02NV_ID at MS02NV_MAGIC and also
+ * a diagnostic status at MS02NV_DIAG.
+ */
+ ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG));
+ ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC));
+ err = get_dbe(ms02nv_magic, ms02nv_magicp);
+ if (err)
+ return 0;
+ if (ms02nv_magic != MS02NV_ID)
+ return 0;
+
+ ms02nv_diag = *ms02nv_diagp;
+ size = (ms02nv_diag & MS02NV_DIAG_SIZE_MASK) << MS02NV_DIAG_SIZE_SHIFT;
+ if (size > MS02NV_CSR)
+ size = MS02NV_CSR;
+
+ return size;
+}
+
+static int __init ms02nv_init_one(ulong addr)
+{
+ struct mtd_info *mtd;
+ struct ms02nv_private *mp;
+ struct resource *mod_res;
+ struct resource *diag_res;
+ struct resource *user_res;
+ struct resource *csr_res;
+ ulong fixaddr;
+ size_t size, fixsize;
+
+ static int version_printed;
+
+ int ret = -ENODEV;
+
+ /* The module decodes 8MB of address space. */
+ mod_res = kmalloc(sizeof(*mod_res), GFP_KERNEL);
+ if (!mod_res)
+ return -ENOMEM;
+
+ memset(mod_res, 0, sizeof(*mod_res));
+ mod_res->name = ms02nv_name;
+ mod_res->start = addr;
+ mod_res->end = addr + MS02NV_SLOT_SIZE - 1;
+ mod_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ if (request_resource(&iomem_resource, mod_res) < 0)
+ goto err_out_mod_res;
+
+ size = ms02nv_probe_one(addr);
+ if (!size)
+ goto err_out_mod_res_rel;
+
+ if (!version_printed) {
+ printk(KERN_INFO "%s", version);
+ version_printed = 1;
+ }
+
+ ret = -ENOMEM;
+ mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+ if (!mtd)
+ goto err_out_mod_res_rel;
+ memset(mtd, 0, sizeof(*mtd));
+ mp = kmalloc(sizeof(*mp), GFP_KERNEL);
+ if (!mp)
+ goto err_out_mtd;
+ memset(mp, 0, sizeof(*mp));
+
+ mtd->priv = mp;
+ mp->resource.module = mod_res;
+
+ /* Firmware's diagnostic NVRAM area. */
+ diag_res = kmalloc(sizeof(*diag_res), GFP_KERNEL);
+ if (!diag_res)
+ goto err_out_mp;
+
+ memset(diag_res, 0, sizeof(*diag_res));
+ diag_res->name = ms02nv_res_diag_ram;
+ diag_res->start = addr;
+ diag_res->end = addr + MS02NV_RAM - 1;
+ diag_res->flags = IORESOURCE_BUSY;
+ request_resource(mod_res, diag_res);
+
+ mp->resource.diag_ram = diag_res;
+
+ /* User-available general-purpose NVRAM area. */
+ user_res = kmalloc(sizeof(*user_res), GFP_KERNEL);
+ if (!user_res)
+ goto err_out_diag_res;
+
+ memset(user_res, 0, sizeof(*user_res));
+ user_res->name = ms02nv_res_user_ram;
+ user_res->start = addr + MS02NV_RAM;
+ user_res->end = addr + size - 1;
+ user_res->flags = IORESOURCE_BUSY;
+ request_resource(mod_res, user_res);
+
+ mp->resource.user_ram = user_res;
+
+ /* Control and status register. */
+ csr_res = kmalloc(sizeof(*csr_res), GFP_KERNEL);
+ if (!csr_res)
+ goto err_out_user_res;
+
+ memset(csr_res, 0, sizeof(*csr_res));
+ csr_res->name = ms02nv_res_csr;
+ csr_res->start = addr + MS02NV_CSR;
+ csr_res->end = addr + MS02NV_CSR + 3;
+ csr_res->flags = IORESOURCE_BUSY;
+ request_resource(mod_res, csr_res);
+
+ mp->resource.csr = csr_res;
+
+ mp->addr = phys_to_virt(addr);
+ mp->size = size;
+
+ /*
+ * Hide the firmware's diagnostic area. It may get destroyed
+ * upon a reboot. Take paging into account for mapping support.
+ */
+ fixaddr = (addr + MS02NV_RAM + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+ fixsize = (size - (fixaddr - addr)) & ~(PAGE_SIZE - 1);
+ mp->uaddr = phys_to_virt(fixaddr);
+
+ mtd->type = MTD_RAM;
+ mtd->flags = MTD_CAP_RAM | MTD_XIP;
+ mtd->size = fixsize;
+ mtd->name = (char *)ms02nv_name;
+ mtd->module = THIS_MODULE;
+ mtd->read = ms02nv_read;
+ mtd->write = ms02nv_write;
+
+ ret = -EIO;
+ if (add_mtd_device(mtd)) {
+ printk(KERN_ERR
+ "ms02-nv: Unable to register MTD device, aborting!\n");
+ goto err_out_csr_res;
+ }
+
+ printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMB.\n",
+ mtd->index, ms02nv_name, addr, size >> 20);
+
+ mp->next = root_ms02nv_mtd;
+ root_ms02nv_mtd = mtd;
+
+ return 0;
+
+
+err_out_csr_res:
+ release_resource(csr_res);
+ kfree(csr_res);
+err_out_user_res:
+ release_resource(user_res);
+ kfree(user_res);
+err_out_diag_res:
+ release_resource(diag_res);
+ kfree(diag_res);
+err_out_mp:
+ kfree(mp);
+err_out_mtd:
+ kfree(mtd);
+err_out_mod_res_rel:
+ release_resource(mod_res);
+err_out_mod_res:
+ kfree(mod_res);
+ return ret;
+}
+
+static void __exit ms02nv_remove_one(void)
+{
+ struct mtd_info *mtd = root_ms02nv_mtd;
+ struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+ root_ms02nv_mtd = mp->next;
+
+ del_mtd_device(mtd);
+
+ release_resource(mp->resource.csr);
+ kfree(mp->resource.csr);
+ release_resource(mp->resource.user_ram);
+ kfree(mp->resource.user_ram);
+ release_resource(mp->resource.diag_ram);
+ kfree(mp->resource.diag_ram);
+ release_resource(mp->resource.module);
+ kfree(mp->resource.module);
+ kfree(mp);
+ kfree(mtd);
+}
+
+
+static int __init ms02nv_init(void)
+{
+ volatile u32 *csr;
+ uint stride = 0;
+ int count = 0;
+ int i;
+
+ switch (mips_machtype) {
+ case MACH_DS5000_200:
+ csr = (volatile u32 *)KN02_CSR_ADDR;
+ if (*csr & KN02_CSR_BNK32M)
+ stride = 2;
+ break;
+ case MACH_DS5000_2X0:
+ csr = (volatile u32 *)KN03_MCR_BASE;
+ if (*csr & KN03_MCR_BNK32M)
+ stride = 2;
+ break;
+ default:
+ return -ENODEV;
+ break;
+ }
+
+ for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++)
+ if (!ms02nv_init_one(ms02nv_addrs[i] << stride))
+ count++;
+
+ return (count > 0) ? 0 : -ENODEV;
+}
+
+static void __exit ms02nv_cleanup(void)
+{
+ while (root_ms02nv_mtd)
+ ms02nv_remove_one();
+}
+
+
+module_init(ms02nv_init);
+module_exit(ms02nv_cleanup);
diff -up --recursive --new-file linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.h linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.h
--- linux-mips-2.4.18-20020327.macro/drivers/mtd/devices/ms02-nv.h 1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.4.18-20020327/drivers/mtd/devices/ms02-nv.h 2001-08-12 20:10:10.000000000 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001 Maciej W. Rozycki
+ *
+ * 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/ioport.h>
+#include <linux/mtd/mtd.h>
+
+/* MS02-NV iomem register offsets. */
+#define MS02NV_CSR 0x400000 /* control & status register */
+
+/* MS02-NV memory offsets. */
+#define MS02NV_DIAG 0x0003f8 /* diagnostic status */
+#define MS02NV_MAGIC 0x0003fc /* MS02-NV magic ID */
+#define MS02NV_RAM 0x000400 /* general-purpose RAM start */
+
+/* MS02-NV diagnostic status constants. */
+#define MS02NV_DIAG_SIZE_MASK 0xf0 /* RAM size mask */
+#define MS02NV_DIAG_SIZE_SHIFT 0x10 /* RAM size shift (left) */
+
+/* MS02-NV general constants. */
+#define MS02NV_ID 0x03021966 /* MS02-NV magic ID value */
+#define MS02NV_SLOT_SIZE 0x800000 /* size of the address space
+ decoded by the module */
+
+typedef volatile u32 ms02nv_uint;
+
+struct ms02nv_private {
+ struct mtd_info *next;
+ struct {
+ struct resource *module;
+ struct resource *diag_ram;
+ struct resource *user_ram;
+ struct resource *csr;
+ } resource;
+ u_char *addr;
+ size_t size;
+ u_char *uaddr;
+};
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [patch] linux 2.4: DEC MS02-NV NVRAM module support
2002-03-28 13:26 [patch] linux 2.4: DEC MS02-NV NVRAM module support Maciej W. Rozycki
@ 2002-03-30 8:19 ` Ralf Baechle
0 siblings, 0 replies; 2+ messages in thread
From: Ralf Baechle @ 2002-03-30 8:19 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: David Woodhouse, Harald Koerfgen, linux-mips, linux-mips
On Thu, Mar 28, 2002 at 02:26:55PM +0100, Maciej W. Rozycki wrote:
> The patch adds support for the DEC MS02-type lithium battery backed-up
> NVRAM board. The board provides 1MB (architecturally up to 4MB) of fast
> SRAM originally meant as a PrestoServe NFS accelerator for the MIPS-based
> DECstations.
>
> The code works fine for me since its creation back in August. It was not
> tested by anyone else -- after announcing the code at the "linux-mips"
> list last year I've read from two volunteers but they did not come back
> with results ever.
>
> I believe it's suitable for inclusion in the official kernel. The patch
> applies both to 2.4.19-pre4 and to the current CVS tree at oss.sgi.com.
Looks good, applied to 2.4 and 2.5.
If you would have submitted this patch without prior testing in August I
certainly would have approved it as well as it had not potencial to break
things for other machines.
Thanks,
Ralf
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2002-03-30 8:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-03-28 13:26 [patch] linux 2.4: DEC MS02-NV NVRAM module support Maciej W. Rozycki
2002-03-30 8:19 ` Ralf Baechle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox