Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/nor More support for CFI NOR.



details:   https://anonhg.NetBSD.org/src/rev/6bb3be733091
branches:  trunk
changeset: 767330:6bb3be733091
user:      cliff <cliff%NetBSD.org@localhost>
date:      Fri Jul 15 19:37:41 2011 +0000

description:
More support for CFI NOR.

diffstat:

 sys/dev/nor/nor.c |  835 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 662 insertions(+), 173 deletions(-)

diffs (truncated from 1068 to 300 lines):

diff -r 56b27a624725 -r 6bb3be733091 sys/dev/nor/nor.c
--- a/sys/dev/nor/nor.c Fri Jul 15 19:30:08 2011 +0000
+++ b/sys/dev/nor/nor.c Fri Jul 15 19:37:41 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nor.c,v 1.1 2011/06/22 21:59:15 ahoka Exp $    */
+/*     $NetBSD: nor.c,v 1.2 2011/07/15 19:37:41 cliff Exp $    */
 
 /*-
  * Copyright (c) 2011 Department of Software Engineering,
@@ -34,9 +34,10 @@
 /* Common driver for NOR chips implementing the ONFI CFI specification */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nor.c,v 1.1 2011/06/22 21:59:15 ahoka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nor.c,v 1.2 2011/07/15 19:37:41 cliff Exp $");
 
 #include "locators.h"
+#include "opt_nor.h"
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -46,18 +47,33 @@
 #include <sys/atomic.h>
 
 #include <dev/flash/flash.h>
+#include <dev/flash/flash_io.h>
 #include <dev/nor/nor.h>
-#include <dev/nor/cfi.h>
+
 
-//#include "opt_nor.h"
+static int nor_match(device_t, cfdata_t, void *);
+static void nor_attach(device_t, device_t, void *);
+static int nor_detach(device_t, int);
+static bool nor_shutdown(device_t, int);
+static int nor_print(void *, const char *);
+static int nor_search(device_t, cfdata_t, const int *, void *);
 
-int nor_match(device_t, cfdata_t, void *);
-void nor_attach(device_t, device_t, void *);
-int nor_detach(device_t, int);
-bool nor_shutdown(device_t, int);
+/* flash interface implementation */
+static int nor_flash_isbad(device_t, flash_off_t, bool *);
+static int nor_flash_markbad(device_t, flash_off_t);
+static int nor_flash_write(device_t, flash_off_t, size_t, size_t *,
+       const u_char *);
+static int nor_flash_read(device_t, flash_off_t, size_t, size_t *, uint8_t *);
+static int nor_flash_erase_all(device_t);
+static int nor_flash_erase(device_t, struct flash_erase_instruction *);
+static int nor_flash_submit(device_t, buf_t *);
 
-int nor_print(void *, const char *);
-static int nor_search(device_t, cfdata_t, const int *, void *);
+/* default functions for driver development */
+static void nor_default_select(device_t, bool);
+static int  nor_default_read_page(device_t, flash_off_t, uint8_t *);
+static int  nor_default_program_page(device_t, flash_off_t, const uint8_t *);
+
+static int nor_scan_media(device_t, struct nor_chip *);
 
 CFATTACH_DECL_NEW(nor, sizeof(struct nor_softc),
     nor_match, nor_attach, nor_detach, NULL);
@@ -69,8 +85,20 @@
 int nor_cachesync_timeout = 1;
 int nor_cachesync_nodenum;
 
+struct flash_interface nor_flash_if = {
+       .type = FLASH_TYPE_NOR,
+
+       .read = nor_flash_read,
+       .write = nor_flash_write,
+       .erase = nor_flash_erase,
+       .block_isbad = nor_flash_isbad,
+       .block_markbad = nor_flash_markbad,
+
+       .submit = nor_flash_submit
+};
+
 #ifdef NOR_VERBOSE
-const struct nor_manufacturer nor_mfrs[] = {
+const nor_manufacturer_t nor_mfrs[] = {
        { NOR_MFR_AMD,          "AMD" },
        { NOR_MFR_FUJITSU,      "Fujitsu" },
        { NOR_MFR_RENESAS,      "Renesas" },
@@ -100,33 +128,44 @@
 #endif
 
 /* ARGSUSED */
-int
+static int
 nor_match(device_t parent, cfdata_t match, void *aux)
 {
        /* pseudo device, always attaches */
        return 1;
 }
 
-void
+static void
 nor_attach(device_t parent, device_t self, void *aux)
 {
-       struct nor_softc *sc = device_private(self);
-       struct nor_attach_args *naa = aux;
-       struct nor_chip *chip = &sc->sc_chip;
+       struct nor_softc * const sc = device_private(self);
+       struct nor_attach_args * const naa = aux;
+       struct nor_chip * const chip = &sc->sc_chip;
 
        sc->sc_dev = self;
-       sc->controller_dev = parent;
-       sc->nor_if = naa->naa_nor_if;
+       sc->sc_controller_dev = parent;
+       sc->sc_nor_if = naa->naa_nor_if;
 
        aprint_naive("\n");
+       aprint_normal("\n");
+
+       if (nor_scan_media(self, chip))
+               return;
+
+       sc->sc_flash_if = nor_flash_if;
+       sc->sc_flash_if.erasesize = chip->nc_block_size;
+       sc->sc_flash_if.page_size = chip->nc_page_size;
+       sc->sc_flash_if.writesize = chip->nc_page_size;
 
        /* allocate cache */
+#ifdef NOTYET
        chip->nc_oob_cache = kmem_alloc(chip->nc_spare_size, KM_SLEEP);
+#endif
        chip->nc_page_cache = kmem_alloc(chip->nc_page_size, KM_SLEEP);
 
        mutex_init(&sc->sc_device_lock, MUTEX_DEFAULT, IPL_NONE);
 
-       if (nor_sync_thread_start(self)) {
+       if (flash_sync_thread_init(&sc->sc_flash_io, self, &sc->sc_flash_if)) {
                goto error;
        }
 
@@ -145,8 +184,11 @@
        config_search_ia(nor_search, self, NULL, NULL);
 
        return;
+
 error:
+#ifdef NOTET
        kmem_free(chip->nc_oob_cache, chip->nc_spare_size);
+#endif
        kmem_free(chip->nc_page_cache, chip->nc_page_size);
        mutex_destroy(&sc->sc_device_lock);
 }
@@ -154,44 +196,25 @@
 static int
 nor_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
 {
-       struct nor_softc *sc = device_private(parent);
-       struct nor_chip *chip = &sc->sc_chip;
-       struct flash_interface *flash_if;
+       struct nor_softc * const sc = device_private(parent);
+       struct nor_chip * const chip = &sc->sc_chip;
        struct flash_attach_args faa;
 
-       flash_if = kmem_alloc(sizeof(*flash_if), KM_SLEEP);
-
-       flash_if->type = FLASH_TYPE_NOR;
-
-       flash_if->read = nor_flash_read;
-       flash_if->write = nor_flash_write;
-       flash_if->erase = nor_flash_erase;
-       flash_if->block_isbad = nor_flash_isbad;
-       flash_if->block_markbad = nor_flash_markbad;
-
-       flash_if->submit = nor_io_submit;
-
-       flash_if->erasesize = chip->nc_block_size;
-       flash_if->page_size = chip->nc_page_size;
-       flash_if->writesize = chip->nc_page_size;
-
-       flash_if->partition.part_offset = cf->cf_loc[FLASHBUSCF_OFFSET];
+       faa.partinfo.part_offset = cf->cf_loc[FLASHBUSCF_OFFSET];
 
        if (cf->cf_loc[FLASHBUSCF_SIZE] == 0) {
-               flash_if->size = chip->nc_size -
-                   flash_if->partition.part_offset;
-               flash_if->partition.part_size = flash_if->size;
+               faa.partinfo.part_size =
+                   chip->nc_size - faa.partinfo.part_offset;
        } else {
-               flash_if->size = cf->cf_loc[FLASHBUSCF_SIZE];
-               flash_if->partition.part_size = cf->cf_loc[FLASHBUSCF_SIZE];
+               faa.partinfo.part_size = cf->cf_loc[FLASHBUSCF_SIZE];
        }
 
        if (cf->cf_loc[FLASHBUSCF_READONLY])
-               flash_if->partition.part_flags = FLASH_PART_READONLY;
+               faa.partinfo.part_flags = FLASH_PART_READONLY;
        else
-               flash_if->partition.part_flags = 0;
+               faa.partinfo.part_flags = 0;
 
-       faa.flash_if = flash_if;
+       faa.flash_if = &sc->sc_flash_if;
 
        if (config_match(parent, cf, &faa)) {
                if (config_attach(parent, cf, &faa, nor_print) != NULL) {
@@ -199,18 +222,16 @@
                } else {
                        return 1;
                }
-       } else {
-               kmem_free(flash_if, sizeof(*flash_if));
        }
 
        return 1;
 }
 
-int
+static int
 nor_detach(device_t self, int flags)
 {
-       struct nor_softc *sc = device_private(self);
-       struct nor_chip *chip = &sc->sc_chip;
+       struct nor_softc * const sc = device_private(self);
+       struct nor_chip * const chip = &sc->sc_chip;
        int error = 0;
 
        error = config_detach_children(self, flags);
@@ -218,12 +239,14 @@
                return error;
        }
 
-       nor_sync_thread_stop(self);
+       flash_sync_thread_destroy(&sc->sc_flash_io);
 #ifdef NOR_BBT
        nor_bbt_detach(self);
 #endif
+#ifdef NOTET
        /* free oob cache */
        kmem_free(chip->nc_oob_cache, chip->nc_spare_size);
+#endif
        kmem_free(chip->nc_page_cache, chip->nc_page_size);
 
        mutex_destroy(&sc->sc_device_lock);
@@ -233,7 +256,7 @@
        return error;
 }
 
-int
+static int
 nor_print(void *aux, const char *pnp)
 {
        if (pnp != NULL)
@@ -244,40 +267,66 @@
 
 /* ask for a nor driver to attach to the controller */
 device_t
-nor_attach_mi(struct nor_interface *nor_if, device_t parent)
+nor_attach_mi(struct nor_interface * const nor_if, device_t parent)
 {
        struct nor_attach_args arg;
 
        KASSERT(nor_if != NULL);
 
+       if (nor_if->select == NULL)
+               nor_if->select = &nor_default_select;
+       if (nor_if->read_page == NULL)
+               nor_if->read_page = &nor_default_read_page;
+       if (nor_if->program_page == NULL)
+               nor_if->program_page = &nor_default_program_page;
+
        arg.naa_nor_if = nor_if;
-       return config_found_ia(parent, "norbus", &arg, nor_print);
+
+       device_t dev = config_found_ia(parent, "norbus", &arg, nor_print);
+
+       return dev;
 }
 
+static void
+nor_default_select(device_t self, bool n)
+{
+       /* do nothing */
+       return;
+}
+
+static int
+nor_flash_submit(device_t self, buf_t * const bp)
+{
+       struct nor_softc * const sc = device_private(self);
+
+       return flash_io_submit(&sc->sc_flash_io, bp);
+}
+
+
 /* default everything to reasonable values, to ease future api changes */
 void
-nor_init_interface(struct nor_interface *interface)
+nor_init_interface(struct nor_interface * const nor_if)
 {
-       interface->select = &nor_default_select;
-       interface->read_1 = NULL;



Home | Main Index | Thread Index | Old Index