Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/nand Add support for legacy devices not supporting t...
details: https://anonhg.NetBSD.org/src/rev/33b4231c6267
branches: trunk
changeset: 763048:33b4231c6267
user: ahoka <ahoka%NetBSD.org@localhost>
date: Wed Mar 09 10:05:08 2011 +0000
description:
Add support for legacy devices not supporting the ONFI READ_PARAMETER_PAGE
command with example usage for Micron chips
diffstat:
sys/dev/nand/files.nand | 3 +-
sys/dev/nand/nand.c | 88 ++++++++++++++++++++++++++++++---------------
sys/dev/nand/nand.h | 17 ++++++--
sys/dev/nand/nand_micron.c | 77 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 150 insertions(+), 35 deletions(-)
diffs (truncated from 335 to 300 lines):
diff -r 6b2c549d8a01 -r 33b4231c6267 sys/dev/nand/files.nand
--- a/sys/dev/nand/files.nand Wed Mar 09 09:17:12 2011 +0000
+++ b/sys/dev/nand/files.nand Wed Mar 09 10:05:08 2011 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.nand,v 1.1 2011/02/26 18:07:31 ahoka Exp $
+# $NetBSD: files.nand,v 1.2 2011/03/09 10:05:08 ahoka Exp $
define nandbus { }
@@ -9,6 +9,7 @@
file dev/nand/hamming.c nand
file dev/nand/nand_bbt.c nand
file dev/nand/nand_crc.c nand
+file dev/nand/nand_micron.c nand
defpseudodev nandemulator: nandbus
file dev/nand/nandemulator.c nandemulator
diff -r 6b2c549d8a01 -r 33b4231c6267 sys/dev/nand/nand.c
--- a/sys/dev/nand/nand.c Wed Mar 09 09:17:12 2011 +0000
+++ b/sys/dev/nand/nand.c Wed Mar 09 10:05:08 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nand.c,v 1.2 2011/03/09 07:49:15 ahoka Exp $ */
+/* $NetBSD: nand.c,v 1.3 2011/03/09 10:05:08 ahoka Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -34,7 +34,7 @@
/* Common driver for NAND chips implementing the ONFI 2.2 specification */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nand.c,v 1.2 2011/03/09 07:49:15 ahoka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nand.c,v 1.3 2011/03/09 10:05:08 ahoka Exp $");
#include "locators.h"
@@ -117,8 +117,10 @@
aprint_error("NAND chip is write protected!\n");
return;
}
- if (nand_scan_media(self, chip))
+
+ if (nand_scan_media(self, chip)) {
return;
+ }
/* allocate cache */
chip->nc_oob_cache = kmem_alloc(chip->nc_spare_size, KM_SLEEP);
@@ -281,6 +283,19 @@
}
#endif
+static int
+nand_read_legacy_parameters(device_t self, struct nand_chip *chip)
+{
+ switch (chip->nc_manf_id) {
+ case NAND_MFR_MICRON:
+ return nand_read_parameters_micron(self, chip);
+ default:
+ return 1;
+ }
+
+ return 0;
+}
+
/**
* scan media to determine the chip's properties
* this function resets the device
@@ -296,6 +311,7 @@
nand_command(self, ONFI_RESET);
nand_select(self, false);
+ /* check if the device implements the ONFI standard */
nand_select(self, true);
nand_command(self, ONFI_READ_ID);
nand_address(self, 0x20);
@@ -307,24 +323,48 @@
if (onfi_signature[0] != 'O' || onfi_signature[1] != 'N' ||
onfi_signature[2] != 'F' || onfi_signature[3] != 'I') {
- aprint_error_dev(self,
- "device does not support the ONFI specification\n");
+ chip->nc_isonfi = false;
+
+ aprint_normal(": Legacy NAND Flash\n");
+
+ nand_readid(self, chip);
- return 1;
+ if (nand_read_legacy_parameters(self, chip)) {
+ aprint_error_dev(self,
+ "can't read device parameters for legacy chip\n");
+ return 1;
+ }
+ } else {
+ chip->nc_isonfi = true;
+
+ aprint_normal(": ONFI NAND Flash\n");
+
+ nand_readid(self, chip);
+ nand_read_parameter_page(self, chip);
}
- nand_readid(self, chip);
-
- aprint_normal(": NAND Flash\n");
-
- aprint_debug_dev(self,
+#ifdef NAND_VERBOSE
+ aprint_normal_dev(self,
"manufacturer id: 0x%.2x (%s), device id: 0x%.2x\n",
chip->nc_manf_id,
nand_midtoname(chip->nc_manf_id),
chip->nc_dev_id);
+#endif
- nand_read_parameter_page(self, chip);
+ aprint_normal_dev(self,
+ "page size: %u bytes, spare size: %u bytes, block size: %u bytes\n",
+ chip->nc_page_size, chip->nc_spare_size, chip->nc_block_size);
+ aprint_normal_dev(self,
+ "LUN size: %u blocks, LUNs: %u, total storage size: %u MB\n",
+ chip->nc_lun_blocks, chip->nc_num_luns,
+ chip->nc_size / 1024 / 1024);
+
+#ifdef NAND_VERBOSE
+ aprint_normal_dev(self, "column cycles: %d, row cycles: %d\n",
+ chip->nc_addr_cycles_column, chip->nc_addr_cycles_row);
+#endif
+
ecc = chip->nc_ecc = &sc->nand_if->ecc;
/*
@@ -388,12 +428,13 @@
nand_select(self, true);
nand_command(self, ONFI_READ_ID);
nand_address(self, 0x00);
+
nand_read_byte(self, &chip->nc_manf_id);
nand_read_byte(self, &chip->nc_dev_id);
+
nand_select(self, false);
}
-/* read the parameter page. TODO: check CRC! */
static void
nand_read_parameter_page(device_t self, struct nand_chip *chip)
{
@@ -435,20 +476,10 @@
aprint_normal_dev(self, "vendor: %s, model: %s\n", vendor, model);
- aprint_normal_dev(self,
- "page size: %u bytes, spare size: %u bytes, block size: %u bytes\n",
- params.param_pagesize, params.param_sparesize,
- params.param_blocksize * params.param_pagesize);
-
- aprint_normal_dev(self,
- "LUN size: %u blocks, LUNs: %u, total storage size: %u MB\n",
- params.param_lunsize, params.param_numluns,
- params.param_blocksize * params.param_pagesize *
- params.param_lunsize * params.param_numluns / 1024 / 1024);
-
/* XXX TODO multiple LUNs */
- if (__predict_false(params.param_numluns != 1))
+ if (__predict_false(params.param_numluns != 1)) {
panic("more than one LUNs are not supported yet!\n");
+ }
chip->nc_size = params.param_pagesize * params.param_blocksize *
params.param_lunsize * params.param_numluns;
@@ -457,17 +488,14 @@
chip->nc_block_pages = params.param_blocksize;
chip->nc_block_size = params.param_blocksize * params.param_pagesize;
chip->nc_spare_size = params.param_sparesize;
+ chip->nc_lun_blocks = params.param_lunsize;
+ chip->nc_num_luns = params.param_numluns;
/* the lower 4 bits contain the row address cycles */
chip->nc_addr_cycles_row = params.param_addr_cycles & 0x07;
/* the upper 4 bits contain the column address cycles */
chip->nc_addr_cycles_column = (params.param_addr_cycles & ~0x07) >> 4;
-#ifdef NAND_VERBOSE
- aprint_normal_dev(self, "column cycles: %d, row cycles: %d\n",
- chip->nc_addr_cycles_column, chip->nc_addr_cycles_row);
-#endif
-
if (params.param_features & ONFI_FEATURE_16BIT)
chip->nc_flags |= NC_BUSWIDTH_16;
diff -r 6b2c549d8a01 -r 33b4231c6267 sys/dev/nand/nand.h
--- a/sys/dev/nand/nand.h Wed Mar 09 09:17:12 2011 +0000
+++ b/sys/dev/nand/nand.h Wed Mar 09 10:05:08 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nand.h,v 1.2 2011/03/05 06:28:29 jruoho Exp $ */
+/* $NetBSD: nand.h,v 1.3 2011/03/09 10:05:08 ahoka Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -64,7 +64,7 @@
void nand_markbad(device_t, size_t);
int nand_read_page(device_t, size_t, uint8_t *);
-int nand_read_oob(device_t self, size_t page, void *oob);
+int nand_read_oob(device_t, size_t, void *);
/*
* default functions for driver development
@@ -154,6 +154,7 @@
* about the NAND chip.
*/
struct nand_chip {
+ struct nand_ecc *nc_ecc; /* ecc information */
uint8_t *nc_oob_cache; /* buffer for oob cache */
uint8_t *nc_page_cache; /* buffer for page cache */
uint8_t *nc_ecc_cache;
@@ -162,19 +163,20 @@
size_t nc_block_pages; /* block size in pages */
size_t nc_block_size; /* block size in bytes */
size_t nc_spare_size; /* spare (oob) size in bytes */
+ uint32_t nc_lun_blocks; /* LUN size in blocks */
uint32_t nc_flags; /* bitfield flags */
uint32_t nc_quirks; /* bitfield quirks */
unsigned int nc_page_shift; /* page shift for page alignment */
unsigned int nc_page_mask; /* page mask for page alignment */
unsigned int nc_block_shift; /* write shift */
unsigned int nc_block_mask; /* write mask */
+ uint8_t nc_num_luns; /* number of LUNs */
uint8_t nc_manf_id; /* manufacturer id */
uint8_t nc_dev_id; /* device id */
uint8_t nc_addr_cycles_row; /* row cycles for addressing */
uint8_t nc_addr_cycles_column; /* column cycles for addressing */
uint8_t nc_badmarker_offs; /* offset for marking bad blocks */
-
- struct nand_ecc *nc_ecc;
+ bool nc_isonfi; /* if the device is onfi compliant */
};
struct nand_write_cache {
@@ -450,6 +452,13 @@
extern const struct nand_manufacturer nand_mfrs[];
+/*
+ * Manufacturer specific parameter functions
+ */
+int nand_read_parameters_micron(device_t, struct nand_chip *);
+
+/* debug inlines */
+
static inline void
nand_dump_data(const char *name, void *data, size_t len)
{
diff -r 6b2c549d8a01 -r 33b4231c6267 sys/dev/nand/nand_micron.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/nand/nand_micron.c Wed Mar 09 10:05:08 2011 +0000
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2011 Department of Software Engineering,
+ * University of Szeged, Hungary
+ * Copyright (c) 2011 Adam Hoka <ahoka%NetBSD.org@localhost>
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by the Department of Software Engineering, University of Szeged, Hungary
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Device specific functions for legacy Micron NAND chips
+ *
+ * Currently supported:
+ * MT29F2G08AACWP, MT29F4G08BACWP, MT29F8G08FACWP
+ */
+
+#include "nand.h"
+#include "onfi.h"
+
+int
Home |
Main Index |
Thread Index |
Old Index