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