diff --git a/sys/dev/nand/files.nand b/sys/dev/nand/files.nand index 1f78a348f3e9..4131476d1b23 100644 --- a/sys/dev/nand/files.nand +++ b/sys/dev/nand/files.nand @@ -1,4 +1,4 @@ -# $NetBSD: files.nand,v 1.2 2011/03/09 10:05:08 ahoka Exp $ +# $NetBSD: files.nand,v 1.3 2011/03/27 13:33:04 ahoka Exp $ define nandbus { } @@ -15,3 +15,5 @@ defpseudodev nandemulator: nandbus file dev/nand/nandemulator.c nandemulator defflag opt_nand.h NAND_BBT +defflag opt_nand.h NAND_DEBUG +defflag opt_nand.h NAND_VERBOSE diff --git a/sys/dev/nand/nand.c b/sys/dev/nand/nand.c index ebe7166643c7..f5b01e4beb34 100644 --- a/sys/dev/nand/nand.c +++ b/sys/dev/nand/nand.c @@ -1,4 +1,4 @@ -/* $NetBSD: nand.c,v 1.5 2011/03/09 12:33:59 ahoka Exp $ */ +/* $NetBSD: nand.c,v 1.6 2011/03/27 13:33:04 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 -__KERNEL_RCSID(0, "$NetBSD: nand.c,v 1.5 2011/03/09 12:33:59 ahoka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nand.c,v 1.6 2011/03/27 13:33:04 ahoka Exp $"); #include "locators.h" @@ -63,9 +63,7 @@ int nand_print(void *, const char *); static int nand_search(device_t, cfdata_t, const int *, void *); static void nand_address_row(device_t, size_t); static void nand_address_column(device_t, size_t, size_t); -static void nand_readid(device_t, struct nand_chip *); -static void nand_read_parameter_page(device_t, struct nand_chip *); -static const char *nand_midtoname(int); +static int nand_fill_chip_structure(device_t, struct nand_chip *); static int nand_scan_media(device_t, struct nand_chip *); static bool nand_check_wp(device_t); @@ -79,6 +77,7 @@ int nanddebug = NAND_DEBUG; int nand_cachesync_timeout = 1; int nand_cachesync_nodenum; +#ifdef NAND_VERBOSE const struct nand_manufacturer nand_mfrs[] = { { NAND_MFR_AMD, "AMD" }, { NAND_MFR_FUJITSU, "Fujitsu" }, @@ -92,6 +91,22 @@ const struct nand_manufacturer nand_mfrs[] = { { NAND_MFR_UNKNOWN, "Unknown" } }; +static const char * +nand_midtoname(int id) +{ + int i; + + for (i = 0; nand_mfrs[i].id != 0; i++) { + if (nand_mfrs[i].id == id) + return nand_mfrs[i].name; + } + + KASSERT(nand_mfrs[i].id == 0); + + return nand_mfrs[i].name; +} +#endif + /* ARGSUSED */ int nand_match(device_t parent, cfdata_t match, void *aux) @@ -108,7 +123,7 @@ nand_attach(device_t parent, device_t self, void *aux) struct nand_chip *chip = &sc->sc_chip; sc->sc_dev = self; - sc->nand_dev = parent; + sc->controller_dev = parent; sc->nand_if = naa->naa_nand_if; aprint_naive("\n"); @@ -238,6 +253,7 @@ nand_print(void *aux, const char *pnp) return UNCONF; } +/* ask for a nand driver to attach to the controller */ device_t nand_attach_mi(struct nand_interface *nand_if, device_t parent) { @@ -245,23 +261,50 @@ nand_attach_mi(struct nand_interface *nand_if, device_t parent) KASSERT(nand_if != NULL); + /* fill the defaults if we have null pointers */ + if (nand_if->program_page == NULL) { + nand_if->program_page = &nand_default_program_page; + } + + if (nand_if->read_page == NULL) { + nand_if->read_page = &nand_default_read_page; + } + arg.naa_nand_if = nand_if; return config_found_ia(parent, "nandbus", &arg, nand_print); } -static const char * -nand_midtoname(int id) +/* default everything to reasonable values, to ease future api changes */ +void +nand_init_interface(struct nand_interface *interface) { - int i; + interface->select = &nand_default_select; + interface->command = NULL; + interface->address = NULL; + interface->read_buf_byte = NULL; + interface->read_buf_word = NULL; + interface->read_byte = NULL; + interface->read_word = NULL; + interface->write_buf_byte = NULL; + interface->write_buf_word = NULL; + interface->write_byte = NULL; + interface->write_word = NULL; + interface->busy = NULL; - for (i = 0; nand_mfrs[i].id != 0; i++) { - if (nand_mfrs[i].id == id) - return nand_mfrs[i].name; - } + /*- + * most drivers dont want to change this, but some implement + * read/program in one step + */ + interface->program_page = &nand_default_program_page; + interface->read_page = &nand_default_read_page; - KASSERT(nand_mfrs[i].id == 0); - - return nand_mfrs[i].name; + /* default to soft ecc, that should work everywhere */ + interface->ecc_compute = &nand_default_ecc_compute; + interface->ecc_correct = &nand_default_ecc_correct; + interface->ecc_prepare = NULL; + interface->ecc.necc_code_size = 3; + interface->ecc.necc_block_size = 256; + interface->ecc.necc_type = NAND_ECC_TYPE_SW; } #if 0 @@ -284,7 +327,7 @@ nand_quirks(device_t self, struct nand_chip *chip) #endif static int -nand_read_legacy_parameters(device_t self, struct nand_chip *chip) +nand_fill_chip_structure_legacy(device_t self, struct nand_chip *chip) { switch (chip->nc_manf_id) { case NAND_MFR_MICRON: @@ -327,9 +370,9 @@ nand_scan_media(device_t self, struct nand_chip *chip) aprint_normal(": Legacy NAND Flash\n"); - nand_readid(self, chip); + nand_read_id(self, &chip->nc_manf_id, &chip->nc_dev_id); - if (nand_read_legacy_parameters(self, chip)) { + if (nand_fill_chip_structure_legacy(self, chip)) { aprint_error_dev(self, "can't read device parameters for legacy chip\n"); return 1; @@ -339,8 +382,14 @@ nand_scan_media(device_t self, struct nand_chip *chip) aprint_normal(": ONFI NAND Flash\n"); - nand_readid(self, chip); - nand_read_parameter_page(self, chip); + nand_read_id(self, &chip->nc_manf_id, &chip->nc_dev_id); + + if (nand_fill_chip_structure(self, chip)) { + aprint_error_dev(self, + "can't read device parameters\n"); + + return 1; + } } #ifdef NAND_VERBOSE @@ -425,37 +474,41 @@ nand_scan_media(device_t self, struct nand_chip *chip) return 0; } -static void -nand_readid(device_t self, struct nand_chip *chip) +void +nand_read_id(device_t self, uint8_t *manf, uint8_t *dev) { 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_read_byte(self, manf); + nand_read_byte(self, dev); nand_select(self, false); } -static void -nand_read_parameter_page(device_t self, struct nand_chip *chip) +int +nand_read_parameter_page(device_t self, struct onfi_parameter_page *params) { - struct onfi_parameter_page params; uint8_t *bufp; - uint8_t vendor[13], model[21]; uint16_t crc; - int i; + int i;//, tries = 0; - KASSERT(sizeof(params) == 256); + KASSERT(sizeof(*params) == 256); +//read_params: +// tries++; + nand_select(self, true); nand_command(self, ONFI_READ_PARAMETER_PAGE); nand_address(self, 0x00); nand_busy(self); - bufp = (uint8_t *)¶ms; + /* TODO check the signature if it contains at least 2 letters */ + + bufp = (uint8_t *)params; + /* XXX why i am not using read_buf? */ for (i = 0; i < 256; i++) { nand_read_byte(self, &bufp[i]); } @@ -464,9 +517,24 @@ nand_read_parameter_page(device_t self, struct nand_chip *chip) /* validate the parameter page with the crc */ crc = nand_crc16(bufp, 254); - if (crc != params.param_integrity_crc) { + if (crc != params->param_integrity_crc) { aprint_error_dev(self, "parameter page crc check failed\n"); /* TODO: we should read the next parameter page copy */ + return 1; + } + + return 0; +} + +static int +nand_fill_chip_structure(device_t self, struct nand_chip *chip) +{ + struct onfi_parameter_page params; + uint8_t vendor[13], model[21]; + int i; + + if (nand_read_parameter_page(self, ¶ms)) { + return 1; } /* strip manufacturer and model string */ @@ -480,8 +548,11 @@ nand_read_parameter_page(device_t self, struct nand_chip *chip) aprint_normal_dev(self, "vendor: %s, model: %s\n", vendor, model); /* XXX TODO multiple LUNs */ - if (__predict_false(params.param_numluns != 1)) { - panic("more than one LUNs are not supported yet!\n"); + if (params.param_numluns != 1) { + aprint_error_dev(self, + "more than one LUNs are not supported yet!\n"); + + return 1; } chip->nc_size = params.param_pagesize * params.param_blocksize * @@ -504,6 +575,8 @@ nand_read_parameter_page(device_t self, struct nand_chip *chip) if (params.param_features & ONFI_FEATURE_EXTENDED_PARAM) chip->nc_flags |= NC_EXTENDED_PARAM; + + return 0; } /* ARGSUSED */ @@ -583,9 +656,9 @@ nand_prepare_read(device_t self, flash_addr_t row, flash_addr_t column) nand_busy(self); } -/* read a page with ecc correction */ +/* read a page with ecc correction, default implementation */ int -nand_read_page(device_t self, size_t offset, uint8_t *data) +nand_default_read_page(device_t self, size_t offset, uint8_t *data) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; @@ -672,8 +745,8 @@ nand_read_page(device_t self, size_t offset, uint8_t *data) return 0; } -static int -nand_program_page(device_t self, size_t page, const uint8_t *data) +int +nand_default_program_page(device_t self, size_t page, const uint8_t *data) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; @@ -739,8 +812,9 @@ nand_program_page(device_t self, size_t page, const uint8_t *data) return 0; } +/* read the OOB of a page */ int -nand_read_oob(device_t self, size_t page, void *oob) +nand_read_oob(device_t self, size_t page, uint8_t *oob) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; diff --git a/sys/dev/nand/nand.h b/sys/dev/nand/nand.h index 89cebf9c5073..415f0d9d633d 100644 --- a/sys/dev/nand/nand.h +++ b/sys/dev/nand/nand.h @@ -1,4 +1,4 @@ -/* $NetBSD: nand.h,v 1.3 2011/03/09 10:05:08 ahoka Exp $ */ +/* $NetBSD: nand.h,v 1.4 2011/03/27 13:33:04 ahoka Exp $ */ /*- * Copyright (c) 2010 Department of Software Engineering, @@ -41,52 +41,9 @@ #include #include +#include #include -/* flash interface implementation */ -int nand_flash_isbad(device_t, uint64_t); -int nand_flash_markbad(device_t, uint64_t); -int nand_flash_write(device_t, off_t, size_t, size_t *, const u_char *); -int nand_flash_read(device_t, off_t, size_t, size_t *, uint8_t *); -int nand_flash_erase(device_t, struct flash_erase_instruction *); - -/* nand specific functions */ -int nand_erase_block(device_t, size_t); - -int nand_io_submit(device_t, struct buf *); -void nand_sync_thread(void *); -int nand_sync_thread_start(device_t); -void nand_sync_thread_stop(device_t); - -bool nand_isfactorybad(device_t, flash_addr_t); -bool nand_iswornoutbad(device_t, flash_addr_t); -bool nand_isbad(device_t, flash_addr_t); -void nand_markbad(device_t, size_t); - -int nand_read_page(device_t, size_t, uint8_t *); -int nand_read_oob(device_t, size_t, void *); - -/* - * default functions for driver development - */ -void nand_default_select(device_t, bool); -int nand_default_ecc_compute(device_t, const uint8_t *, uint8_t *); -int nand_default_ecc_correct(device_t, uint8_t *, const uint8_t *, - const uint8_t *); - -static inline void nand_busy(device_t); -static inline void nand_select(device_t, bool); -static inline void nand_command(device_t, uint8_t); -static inline void nand_address(device_t, uint32_t); -static inline void nand_read_buf_byte(device_t, void *, size_t); -static inline void nand_read_buf_word(device_t, void *, size_t); -static inline void nand_read_byte(device_t, uint8_t *); -static inline void nand_write_buf_byte(device_t, const void *, size_t); -static inline void nand_write_buf_word(device_t, const void *, size_t); -//static inline bool nand_block_isbad(device_t, off_t); -//static inline void nand_block_markbad(device_t, off_t); -//static inline bool nand_isbusy(device_t); - //#define NAND_DEBUG 1 #ifdef NAND_DEBUG #define DPRINTF(x) if (nanddebug) printf x @@ -96,7 +53,7 @@ static inline void nand_write_buf_word(device_t, const void *, size_t); #define DPRINTFN(n,x) #endif -#define NAND_VERBOSE +//#define NAND_VERBOSE /* same as in linux for compatibility */ enum { @@ -192,7 +149,7 @@ struct nand_write_cache { /* driver softc for nand */ struct nand_softc { device_t sc_dev; - device_t nand_dev; + device_t controller_dev; struct nand_interface *nand_if; void *nand_softc; struct nand_chip sc_chip; @@ -213,7 +170,8 @@ struct nand_softc { /* structure holding the nand api */ struct nand_interface { - void (*select) (device_t, bool); + /* basic nand controller commands */ + void (*select) (device_t, bool); /* optional */ void (*command) (device_t, uint8_t); void (*address) (device_t, uint8_t); void (*read_buf_byte) (device_t, void *, size_t); @@ -226,12 +184,17 @@ struct nand_interface void (*write_word) (device_t, uint16_t); void (*busy) (device_t); + /* "smart" controllers may override read/program functions */ + int (*read_page) (device_t, size_t, uint8_t *); /* optional */ + int (*program_page) (device_t, size_t, const uint8_t *); /* optional */ + /* functions specific to ecc computation */ - int (*ecc_prepare)(device_t, int); + int (*ecc_prepare)(device_t, int); /* optional */ int (*ecc_compute)(device_t, const uint8_t *, uint8_t *); int (*ecc_correct)(device_t, uint8_t *, const uint8_t *, const uint8_t *); + /* information for the ecc engine */ struct nand_ecc ecc; /* flash partition information */ @@ -244,23 +207,21 @@ struct nand_attach_args { struct nand_interface *naa_nand_if; }; -device_t nand_attach_mi(struct nand_interface *nand_if, device_t dev); - static inline void nand_busy(device_t device) { struct nand_softc *sc = device_private(device); KASSERT(sc->nand_if->select != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->select(sc->nand_dev, true); + sc->nand_if->select(sc->controller_dev, true); if (sc->nand_if->busy != NULL) { - sc->nand_if->busy(sc->nand_dev); + sc->nand_if->busy(sc->controller_dev); } - sc->nand_if->select(sc->nand_dev, false); + sc->nand_if->select(sc->controller_dev, false); } static inline void @@ -269,9 +230,9 @@ nand_select(device_t self, bool enable) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->select != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->select(sc->nand_dev, enable); + sc->nand_if->select(sc->controller_dev, enable); } static inline void @@ -280,9 +241,9 @@ nand_address(device_t self, uint32_t address) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->address != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->address(sc->nand_dev, address); + sc->nand_if->address(sc->controller_dev, address); } static inline void @@ -291,9 +252,9 @@ nand_command(device_t self, uint8_t command) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->command != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->command(sc->nand_dev, command); + sc->nand_if->command(sc->controller_dev, command); } static inline void @@ -302,9 +263,9 @@ nand_read_byte(device_t self, uint8_t *data) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->read_byte != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->read_byte(sc->nand_dev, data); + sc->nand_if->read_byte(sc->controller_dev, data); } static inline void @@ -313,9 +274,9 @@ nand_write_byte(device_t self, uint8_t data) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->write_byte != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->write_byte(sc->nand_dev, data); + sc->nand_if->write_byte(sc->controller_dev, data); } static inline void @@ -324,9 +285,9 @@ nand_read_word(device_t self, uint16_t *data) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->read_word != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->read_word(sc->nand_dev, data); + sc->nand_if->read_word(sc->controller_dev, data); } static inline void @@ -335,9 +296,9 @@ nand_write_word(device_t self, uint16_t data) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->write_word != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->write_word(sc->nand_dev, data); + sc->nand_if->write_word(sc->controller_dev, data); } static inline void @@ -346,9 +307,9 @@ nand_read_buf_byte(device_t self, void *buf, size_t size) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->read_buf_byte != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->read_buf_byte(sc->nand_dev, buf, size); + sc->nand_if->read_buf_byte(sc->controller_dev, buf, size); } static inline void @@ -357,9 +318,9 @@ nand_read_buf_word(device_t self, void *buf, size_t size) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->read_buf_word != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->read_buf_word(sc->nand_dev, buf, size); + sc->nand_if->read_buf_word(sc->controller_dev, buf, size); } static inline void @@ -368,9 +329,9 @@ nand_write_buf_byte(device_t self, const void *buf, size_t size) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->write_buf_byte != NULL); - KASSERT(sc->nand_dev != NULL); - - sc->nand_if->write_buf_byte(sc->nand_dev, buf, size); + KASSERT(sc->controller_dev != NULL); + + sc->nand_if->write_buf_byte(sc->controller_dev, buf, size); } static inline void @@ -379,9 +340,9 @@ nand_write_buf_word(device_t self, const void *buf, size_t size) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->write_buf_word != NULL); - KASSERT(sc->nand_dev != NULL); - - sc->nand_if->write_buf_word(sc->nand_dev, buf, size); + KASSERT(sc->controller_dev != NULL); + + sc->nand_if->write_buf_word(sc->controller_dev, buf, size); } static inline int @@ -391,9 +352,9 @@ nand_ecc_correct(device_t self, uint8_t *data, const uint8_t *oldcode, struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->ecc_correct != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - return sc->nand_if->ecc_correct(sc->nand_dev, data, oldcode, newcode); + return sc->nand_if->ecc_correct(sc->controller_dev, data, oldcode, newcode); } static inline void @@ -402,9 +363,9 @@ nand_ecc_compute(device_t self, const uint8_t *data, uint8_t *code) struct nand_softc *sc = device_private(self); KASSERT(sc->nand_if->ecc_compute != NULL); - KASSERT(sc->nand_dev != NULL); + KASSERT(sc->controller_dev != NULL); - sc->nand_if->ecc_compute(sc->nand_dev, data, code); + sc->nand_if->ecc_compute(sc->controller_dev, data, code); } static inline void @@ -412,10 +373,30 @@ nand_ecc_prepare(device_t self, int mode) { struct nand_softc *sc = device_private(self); - KASSERT(sc->nand_dev != NULL); - + KASSERT(sc->controller_dev != NULL); + if (sc->nand_if->ecc_prepare != NULL) - sc->nand_if->ecc_prepare(sc->nand_dev, mode); + sc->nand_if->ecc_prepare(sc->controller_dev, mode); +} + +static inline int +nand_program_page(device_t self, size_t offset, const uint8_t *data) +{ + struct nand_softc *sc = device_private(self); + + KASSERT(sc->nand_if->program_page != NULL); + + return sc->nand_if->program_page(self, offset, data); +} + +static inline int +nand_read_page(device_t self, size_t offset, uint8_t *data) +{ + struct nand_softc *sc = device_private(self); + + KASSERT(sc->nand_if->read_page != NULL); + + return sc->nand_if->read_page(self, offset, data); } #if 0 @@ -423,11 +404,11 @@ static inline bool nand_block_isbad(device_t self, off_t block) { struct nand_softc *sc = device_private(self); - + KASSERT(sc->nand_if->block_isbad != NULL); - KASSERT(sc->nand_dev != NULL); - - return sc->nand_if->block_isbad(sc->nand_dev, block); + KASSERT(sc->controller_dev != NULL); + + return sc->nand_if->block_isbad(sc->controller_dev, block); } #endif @@ -473,4 +454,58 @@ nand_dump_data(const char *name, void *data, size_t len) printf("\n--------------\n"); } +/* flash interface implementation */ +int nand_flash_isbad(device_t, uint64_t); +int nand_flash_markbad(device_t, uint64_t); +int nand_flash_write(device_t, off_t, size_t, size_t *, const u_char *); +int nand_flash_read(device_t, off_t, size_t, size_t *, uint8_t *); +int nand_flash_erase(device_t, struct flash_erase_instruction *); + +/* nand specific functions */ +int nand_erase_block(device_t, size_t); + +int nand_io_submit(device_t, struct buf *); +void nand_sync_thread(void *); +int nand_sync_thread_start(device_t); +void nand_sync_thread_stop(device_t); + +bool nand_isfactorybad(device_t, flash_addr_t); +bool nand_iswornoutbad(device_t, flash_addr_t); +bool nand_isbad(device_t, flash_addr_t); +void nand_markbad(device_t, size_t); + +//int nand_read_page(device_t, size_t, uint8_t *); +int nand_read_oob(device_t, size_t, uint8_t *); +//int nand_program_page(device_t, size_t, const uint8_t *); + +device_t nand_attach_mi(struct nand_interface *, device_t); +void nand_init_interface(struct nand_interface *); + +/* controller drivers may use these functions to get info about the chip */ +void nand_read_id(device_t, uint8_t *, uint8_t *); +int nand_read_parameter_page(device_t, struct onfi_parameter_page *); + +/* + * default functions for driver development + */ +void nand_default_select(device_t, bool); +int nand_default_ecc_compute(device_t, const uint8_t *, uint8_t *); +int nand_default_ecc_correct(device_t, uint8_t *, const uint8_t *, + const uint8_t *); +int nand_default_read_page(device_t, size_t, uint8_t *); +int nand_default_program_page(device_t, size_t, const uint8_t *); + +static inline void nand_busy(device_t); +static inline void nand_select(device_t, bool); +static inline void nand_command(device_t, uint8_t); +static inline void nand_address(device_t, uint32_t); +static inline void nand_read_buf_byte(device_t, void *, size_t); +static inline void nand_read_buf_word(device_t, void *, size_t); +static inline void nand_read_byte(device_t, uint8_t *); +static inline void nand_write_buf_byte(device_t, const void *, size_t); +static inline void nand_write_buf_word(device_t, const void *, size_t); +//static inline bool nand_block_isbad(device_t, off_t); +//static inline void nand_block_markbad(device_t, off_t); +//static inline bool nand_isbusy(device_t); + #endif /* _NAND_H_ */ diff --git a/sys/dev/nand/nandemulator.c b/sys/dev/nand/nandemulator.c index 51bbb65a8e22..8ff74ffbc6a4 100644 --- a/sys/dev/nand/nandemulator.c +++ b/sys/dev/nand/nandemulator.c @@ -1,4 +1,4 @@ -/* $NetBSD: nandemulator.c,v 1.1 2011/02/26 18:07:31 ahoka Exp $ */ +/* $NetBSD: nandemulator.c,v 1.2 2011/03/27 13:33:04 ahoka Exp $ */ /*- * Copyright (c) 2011 Department of Software Engineering, @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nandemulator.c,v 1.1 2011/02/26 18:07:31 ahoka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nandemulator.c,v 1.2 2011/03/27 13:33:04 ahoka Exp $"); #include #include @@ -182,7 +182,8 @@ nandemulator_attach(device_t parent, device_t self, void *aux) sc->sc_dev = self; - sc->sc_nand_if.select = &nand_default_select; + nand_init_interface(&sc->sc_nand_if); + sc->sc_nand_if.command = &nandemulator_command; sc->sc_nand_if.address = &nandemulator_address; sc->sc_nand_if.read_buf_byte = &nandemulator_read_buf_byte; @@ -195,12 +196,8 @@ nandemulator_attach(device_t parent, device_t self, void *aux) sc->sc_nand_if.write_word = &nandemulator_write_word; sc->sc_nand_if.busy = &nandemulator_busy; - sc->sc_nand_if.ecc_compute = &nand_default_ecc_compute; - sc->sc_nand_if.ecc_correct = &nand_default_ecc_correct; - sc->sc_nand_if.ecc_prepare = NULL; sc->sc_nand_if.ecc.necc_code_size = 3; sc->sc_nand_if.ecc.necc_block_size = 256; - sc->sc_nand_if.ecc.necc_type = NAND_ECC_TYPE_SW; if (!pmf_device_register1(sc->sc_dev, NULL, NULL, NULL)) aprint_error_dev(sc->sc_dev,