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