aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/nand
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2019-06-25 04:50:09 +0000
committerWarner Losh <imp@FreeBSD.org>2019-06-25 04:50:09 +0000
commitf5a95d9a07941650493461c255408f5727d0638b (patch)
treeec681c8739341d8c1e8ff3b891e07a31c0fb3ace /sys/dev/nand
parente861dab451869582008237a8c11e97348d2440ce (diff)
downloadsrc-f5a95d9a0794.tar.gz
src-f5a95d9a0794.zip
Remove NAND and NANDFS support
NANDFS has been broken for years. Remove it. The NAND drivers that remain are for ancient parts that are no longer relevant. They are polled, have terrible performance and just for ancient arm hardware. NAND parts have evolved significantly from this early work and little to none of it would be relevant should someone need to update to support raw nand. This code has been off by default for years and has violated the vnode protocol leading to panics since it was committed. Numerous posts to arch@ and other locations have found no actual users for this software. Relnotes: Yes No Objection From: arch@ Differential Revision: https://reviews.freebsd.org/D20745
Notes
Notes: svn path=/head/; revision=349352
Diffstat (limited to 'sys/dev/nand')
-rw-r--r--sys/dev/nand/nand.c826
-rw-r--r--sys/dev/nand/nand.h415
-rw-r--r--sys/dev/nand/nand_bbt.c275
-rw-r--r--sys/dev/nand/nand_cdev.c454
-rw-r--r--sys/dev/nand/nand_dev.h92
-rw-r--r--sys/dev/nand/nand_ecc_pos.h58
-rw-r--r--sys/dev/nand/nand_generic.c1366
-rw-r--r--sys/dev/nand/nand_geom.c467
-rw-r--r--sys/dev/nand/nand_id.c70
-rw-r--r--sys/dev/nand/nand_if.m168
-rw-r--r--sys/dev/nand/nandbus.c542
-rw-r--r--sys/dev/nand/nandbus.h51
-rw-r--r--sys/dev/nand/nandbus_if.m100
-rw-r--r--sys/dev/nand/nandsim.c670
-rw-r--r--sys/dev/nand/nandsim.h177
-rw-r--r--sys/dev/nand/nandsim_chip.c898
-rw-r--r--sys/dev/nand/nandsim_chip.h161
-rw-r--r--sys/dev/nand/nandsim_ctrl.c398
-rw-r--r--sys/dev/nand/nandsim_log.c188
-rw-r--r--sys/dev/nand/nandsim_log.h54
-rw-r--r--sys/dev/nand/nandsim_swap.c383
-rw-r--r--sys/dev/nand/nandsim_swap.h66
-rw-r--r--sys/dev/nand/nfc_fsl.c717
-rw-r--r--sys/dev/nand/nfc_fsl.h99
-rw-r--r--sys/dev/nand/nfc_if.m165
-rw-r--r--sys/dev/nand/nfc_mv.c238
-rw-r--r--sys/dev/nand/nfc_rb.c321
27 files changed, 0 insertions, 9419 deletions
diff --git a/sys/dev/nand/nand.c b/sys/dev/nand/nand.c
deleted file mode 100644
index 6997ef7f8a0d..000000000000
--- a/sys/dev/nand/nand.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/callout.h>
-#include <sys/sysctl.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-#include <dev/nand/nand_ecc_pos.h>
-#include "nfc_if.h"
-#include "nand_if.h"
-#include "nandbus_if.h"
-#include <machine/stdarg.h>
-
-#define NAND_RESET_DELAY 1000 /* tRST */
-#define NAND_ERASE_DELAY 3000 /* tBERS */
-#define NAND_PROG_DELAY 700 /* tPROG */
-#define NAND_READ_DELAY 50 /* tR */
-
-#define BIT0(x) ((x) & 0x1)
-#define BIT1(x) (BIT0(x >> 1))
-#define BIT2(x) (BIT0(x >> 2))
-#define BIT3(x) (BIT0(x >> 3))
-#define BIT4(x) (BIT0(x >> 4))
-#define BIT5(x) (BIT0(x >> 5))
-#define BIT6(x) (BIT0(x >> 6))
-#define BIT7(x) (BIT0(x >> 7))
-
-#define SOFTECC_SIZE 256
-#define SOFTECC_BYTES 3
-
-int nand_debug_flag = 0;
-SYSCTL_INT(_debug, OID_AUTO, nand_debug, CTLFLAG_RWTUN, &nand_debug_flag, 0,
- "NAND subsystem debug flag");
-
-MALLOC_DEFINE(M_NAND, "NAND", "NAND dynamic data");
-
-static void calculate_ecc(const uint8_t *, uint8_t *);
-static int correct_ecc(uint8_t *, uint8_t *, uint8_t *);
-
-void
-nand_debug(int level, const char *fmt, ...)
-{
- va_list ap;
-
- if (!(nand_debug_flag & level))
- return;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- printf("\n");
-}
-
-void
-nand_init(struct nand_softc *nand, device_t dev, int ecc_mode,
- int ecc_bytes, int ecc_size, uint16_t *eccposition, char *cdev_name)
-{
-
- nand->ecc.eccmode = ecc_mode;
- nand->chip_cdev_name = cdev_name;
-
- if (ecc_mode == NAND_ECC_SOFT) {
- nand->ecc.eccbytes = SOFTECC_BYTES;
- nand->ecc.eccsize = SOFTECC_SIZE;
- } else if (ecc_mode != NAND_ECC_NONE) {
- nand->ecc.eccbytes = ecc_bytes;
- nand->ecc.eccsize = ecc_size;
- if (eccposition)
- nand->ecc.eccpositions = eccposition;
- }
-}
-
-void
-nand_onfi_set_params(struct nand_chip *chip, struct onfi_chip_params *params)
-{
- struct chip_geom *cg;
-
- cg = &chip->chip_geom;
-
- init_chip_geom(cg, params->luns, params->blocks_per_lun,
- params->pages_per_block, params->bytes_per_page,
- params->spare_bytes_per_page);
- chip->t_bers = params->t_bers;
- chip->t_prog = params->t_prog;
- chip->t_r = params->t_r;
- chip->t_ccs = params->t_ccs;
-
- if (params->features & ONFI_FEAT_16BIT)
- chip->flags |= NAND_16_BIT;
-}
-
-void
-nand_set_params(struct nand_chip *chip, struct nand_params *params)
-{
- struct chip_geom *cg;
- uint32_t blocks_per_chip;
-
- cg = &chip->chip_geom;
- blocks_per_chip = (params->chip_size << 20) /
- (params->page_size * params->pages_per_block);
-
- init_chip_geom(cg, 1, blocks_per_chip,
- params->pages_per_block, params->page_size,
- params->oob_size);
-
- chip->t_bers = NAND_ERASE_DELAY;
- chip->t_prog = NAND_PROG_DELAY;
- chip->t_r = NAND_READ_DELAY;
- chip->t_ccs = 0;
-
- if (params->flags & NAND_16_BIT)
- chip->flags |= NAND_16_BIT;
-}
-
-int
-nand_init_stat(struct nand_chip *chip)
-{
- struct block_stat *blk_stat;
- struct page_stat *pg_stat;
- struct chip_geom *cg;
- uint32_t blks, pgs;
-
- cg = &chip->chip_geom;
- blks = cg->blks_per_lun * cg->luns;
- blk_stat = malloc(sizeof(struct block_stat) * blks, M_NAND,
- M_WAITOK | M_ZERO);
- if (!blk_stat)
- return (ENOMEM);
-
- pgs = blks * cg->pgs_per_blk;
- pg_stat = malloc(sizeof(struct page_stat) * pgs, M_NAND,
- M_WAITOK | M_ZERO);
- if (!pg_stat) {
- free(blk_stat, M_NAND);
- return (ENOMEM);
- }
-
- chip->blk_stat = blk_stat;
- chip->pg_stat = pg_stat;
-
- return (0);
-}
-
-void
-nand_destroy_stat(struct nand_chip *chip)
-{
-
- free(chip->pg_stat, M_NAND);
- free(chip->blk_stat, M_NAND);
-}
-
-int
-init_chip_geom(struct chip_geom *cg, uint32_t luns, uint32_t blks_per_lun,
- uint32_t pgs_per_blk, uint32_t pg_size, uint32_t oob_size)
-{
- int shift;
-
- if (!cg)
- return (-1);
-
- cg->luns = luns;
- cg->blks_per_lun = blks_per_lun;
- cg->blks_per_chip = blks_per_lun * luns;
- cg->pgs_per_blk = pgs_per_blk;
-
- cg->page_size = pg_size;
- cg->oob_size = oob_size;
- cg->block_size = cg->page_size * cg->pgs_per_blk;
- cg->chip_size = cg->block_size * cg->blks_per_chip;
-
- shift = fls(cg->pgs_per_blk - 1);
- cg->pg_mask = (1 << shift) - 1;
- cg->blk_shift = shift;
-
- if (cg->blks_per_lun > 0) {
- shift = fls(cg->blks_per_lun - 1);
- cg->blk_mask = ((1 << shift) - 1) << cg->blk_shift;
- } else {
- shift = 0;
- cg->blk_mask = 0;
- }
-
- cg->lun_shift = shift + cg->blk_shift;
- shift = fls(cg->luns - 1);
- cg->lun_mask = ((1 << shift) - 1) << cg->lun_shift;
-
- nand_debug(NDBG_NAND, "Masks: lun 0x%x blk 0x%x page 0x%x\n"
- "Shifts: lun %d blk %d",
- cg->lun_mask, cg->blk_mask, cg->pg_mask,
- cg->lun_shift, cg->blk_shift);
-
- return (0);
-}
-
-int
-nand_row_to_blkpg(struct chip_geom *cg, uint32_t row, uint32_t *lun,
- uint32_t *blk, uint32_t *pg)
-{
-
- if (!cg || !lun || !blk || !pg)
- return (-1);
-
- if (row & ~(cg->lun_mask | cg->blk_mask | cg->pg_mask)) {
- nand_debug(NDBG_NAND,"Address out of bounds\n");
- return (-1);
- }
-
- *lun = (row & cg->lun_mask) >> cg->lun_shift;
- *blk = (row & cg->blk_mask) >> cg->blk_shift;
- *pg = (row & cg->pg_mask);
-
- nand_debug(NDBG_NAND,"address %x-%x-%x\n", *lun, *blk, *pg);
-
- return (0);
-}
-
-int page_to_row(struct chip_geom *cg, uint32_t page, uint32_t *row)
-{
- uint32_t lun, block, pg_in_blk;
-
- if (!cg || !row)
- return (-1);
-
- block = page / cg->pgs_per_blk;
- pg_in_blk = page % cg->pgs_per_blk;
-
- lun = block / cg->blks_per_lun;
- block = block % cg->blks_per_lun;
-
- *row = (lun << cg->lun_shift) & cg->lun_mask;
- *row |= ((block << cg->blk_shift) & cg->blk_mask);
- *row |= (pg_in_blk & cg->pg_mask);
-
- return (0);
-}
-
-int
-nand_check_page_boundary(struct nand_chip *chip, uint32_t page)
-{
- struct chip_geom* cg;
-
- cg = &chip->chip_geom;
- if (page >= (cg->pgs_per_blk * cg->blks_per_lun * cg->luns)) {
- nand_debug(NDBG_GEN,"%s: page number too big %#x\n",
- __func__, page);
- return (1);
- }
-
- return (0);
-}
-
-void
-nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param)
-{
- struct chip_geom *cg;
-
- cg = &chip->chip_geom;
- param->page_size = cg->page_size;
- param->oob_size = cg->oob_size;
-
- param->blocks = cg->blks_per_lun * cg->luns;
- param->pages_per_block = cg->pgs_per_blk;
-}
-
-static uint16_t *
-default_software_ecc_positions(struct nand_chip *chip)
-{
- /* If positions have been set already, use them. */
- if (chip->nand->ecc.eccpositions)
- return (chip->nand->ecc.eccpositions);
-
- /*
- * XXX Note that the following logic isn't really sufficient, especially
- * in the ONFI case where the number of ECC bytes can be dictated by
- * values in the parameters page, and that could lead to needing more
- * byte positions than exist within the tables of software-ecc defaults.
- */
- if (chip->chip_geom.oob_size >= 128)
- return (default_software_ecc_positions_128);
- if (chip->chip_geom.oob_size >= 64)
- return (default_software_ecc_positions_64);
- else if (chip->chip_geom.oob_size >= 16)
- return (default_software_ecc_positions_16);
-
- return (NULL);
-}
-
-static void
-calculate_ecc(const uint8_t *buf, uint8_t *ecc)
-{
- uint8_t p8, byte;
- int i;
-
- memset(ecc, 0, 3);
-
- for (i = 0; i < 256; i++) {
- byte = buf[i];
- ecc[0] ^= (BIT0(byte) ^ BIT2(byte) ^ BIT4(byte) ^
- BIT6(byte)) << 2;
- ecc[0] ^= (BIT1(byte) ^ BIT3(byte) ^ BIT5(byte) ^
- BIT7(byte)) << 3;
- ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT4(byte) ^
- BIT5(byte)) << 4;
- ecc[0] ^= (BIT2(byte) ^ BIT3(byte) ^ BIT6(byte) ^
- BIT7(byte)) << 5;
- ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
- BIT3(byte)) << 6;
- ecc[0] ^= (BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
- BIT7(byte)) << 7;
-
- p8 = BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^
- BIT3(byte) ^ BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^
- BIT7(byte);
-
- if (p8) {
- ecc[2] ^= (0x1 << BIT0(i));
- ecc[2] ^= (0x4 << BIT1(i));
- ecc[2] ^= (0x10 << BIT2(i));
- ecc[2] ^= (0x40 << BIT3(i));
-
- ecc[1] ^= (0x1 << BIT4(i));
- ecc[1] ^= (0x4 << BIT5(i));
- ecc[1] ^= (0x10 << BIT6(i));
- ecc[1] ^= (0x40 << BIT7(i));
- }
- }
- ecc[0] = ~ecc[0];
- ecc[1] = ~ecc[1];
- ecc[2] = ~ecc[2];
- ecc[0] |= 3;
-}
-
-static int
-correct_ecc(uint8_t *buf, uint8_t *calc_ecc, uint8_t *read_ecc)
-{
- uint8_t ecc0, ecc1, ecc2, onesnum, bit, byte;
- uint16_t addr = 0;
-
- ecc0 = calc_ecc[0] ^ read_ecc[0];
- ecc1 = calc_ecc[1] ^ read_ecc[1];
- ecc2 = calc_ecc[2] ^ read_ecc[2];
-
- if (!ecc0 && !ecc1 && !ecc2)
- return (ECC_OK);
-
- addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2);
- addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) |
- (BIT5(ecc2) << 5) | (BIT7(ecc2) << 6);
- addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) |
- (BIT5(ecc1) << 9) | (BIT7(ecc1) << 10);
-
- onesnum = 0;
- while (ecc0 || ecc1 || ecc2) {
- if (ecc0 & 1)
- onesnum++;
- if (ecc1 & 1)
- onesnum++;
- if (ecc2 & 1)
- onesnum++;
-
- ecc0 >>= 1;
- ecc1 >>= 1;
- ecc2 >>= 1;
- }
-
- if (onesnum == 11) {
- /* Correctable error */
- bit = addr & 7;
- byte = addr >> 3;
- buf[byte] ^= (1 << bit);
- return (ECC_CORRECTABLE);
- } else if (onesnum == 1) {
- /* ECC error */
- return (ECC_ERROR_ECC);
- } else {
- /* Uncorrectable error */
- return (ECC_UNCORRECTABLE);
- }
-
- return (0);
-}
-
-int
-nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc)
-{
- int steps = pagesize / SOFTECC_SIZE;
- int i = 0, j = 0;
-
- for (; i < (steps * SOFTECC_BYTES);
- i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
- calculate_ecc(&buf[j], &ecc[i]);
- }
-
- return (0);
-}
-
-int
-nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize,
- uint8_t *readecc, uint8_t *calcecc)
-{
- int steps = pagesize / SOFTECC_SIZE;
- int i = 0, j = 0, ret = 0;
-
- for (i = 0; i < (steps * SOFTECC_BYTES);
- i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
- ret += correct_ecc(&buf[j], &calcecc[i], &readecc[i]);
- if (ret < 0)
- return (ret);
- }
-
- return (ret);
-}
-
-static int
-offset_to_page(struct chip_geom *cg, uint32_t offset)
-{
-
- return (offset / cg->page_size);
-}
-
-int
-nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf,
- uint32_t len)
-{
- struct chip_geom *cg;
- struct nand_ecc_data *eccd;
- struct page_stat *pg_stat;
- device_t nandbus;
- void *oob = NULL;
- uint8_t *ptr;
- uint16_t *eccpos = NULL;
- uint32_t page, num, steps = 0;
- int i, retval = 0, needwrite;
-
- nand_debug(NDBG_NAND,"%p read page %x[%x]", chip, offset, len);
- cg = &chip->chip_geom;
- eccd = &chip->nand->ecc;
- page = offset_to_page(cg, offset);
- num = len / cg->page_size;
-
- if (eccd->eccmode != NAND_ECC_NONE) {
- steps = cg->page_size / eccd->eccsize;
- eccpos = default_software_ecc_positions(chip);
- oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
- }
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- ptr = (uint8_t *)buf;
- while (num--) {
- pg_stat = &(chip->pg_stat[page]);
-
- if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
- retval = ENXIO;
- break;
- }
-
- if (eccd->eccmode != NAND_ECC_NONE) {
- if (NAND_GET_ECC(chip->dev, ptr, eccd->ecccalculated,
- &needwrite)) {
- retval = ENXIO;
- break;
- }
- nand_debug(NDBG_ECC,"%s: ECC calculated:",
- __func__);
- if (nand_debug_flag & NDBG_ECC)
- for (i = 0; i < (eccd->eccbytes * steps); i++)
- printf("%x ", eccd->ecccalculated[i]);
-
- nand_debug(NDBG_ECC,"\n");
-
- if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
- 0)) {
- retval = ENXIO;
- break;
- }
- for (i = 0; i < (eccd->eccbytes * steps); i++)
- eccd->eccread[i] = ((uint8_t *)oob)[eccpos[i]];
-
- nand_debug(NDBG_ECC,"%s: ECC read:", __func__);
- if (nand_debug_flag & NDBG_ECC)
- for (i = 0; i < (eccd->eccbytes * steps); i++)
- printf("%x ", eccd->eccread[i]);
- nand_debug(NDBG_ECC,"\n");
-
- retval = NAND_CORRECT_ECC(chip->dev, ptr, eccd->eccread,
- eccd->ecccalculated);
-
- nand_debug(NDBG_ECC, "NAND_CORRECT_ECC() returned %d",
- retval);
-
- if (retval == 0)
- pg_stat->ecc_stat.ecc_succeded++;
- else if (retval > 0) {
- pg_stat->ecc_stat.ecc_corrected += retval;
- retval = ECC_CORRECTABLE;
- } else {
- pg_stat->ecc_stat.ecc_failed++;
- break;
- }
- }
-
- pg_stat->page_read++;
- page++;
- ptr += cg->page_size;
- }
-
- NANDBUS_UNLOCK(nandbus);
-
- if (oob)
- free(oob, M_NAND);
-
- return (retval);
-}
-
-int
-nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
- uint32_t len)
-{
- struct chip_geom *cg;
- device_t nandbus;
- uint8_t *ptr;
- uint32_t page, num, end, begin = 0, begin_off;
- int retval = 0;
-
- cg = &chip->chip_geom;
- page = offset_to_page(cg, offset);
- begin_off = offset - page * cg->page_size;
- if (begin_off) {
- begin = cg->page_size - begin_off;
- len -= begin;
- }
- num = len / cg->page_size;
- end = len % cg->page_size;
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- ptr = (uint8_t *)buf;
- if (begin_off) {
- if (NAND_READ_PAGE(chip->dev, page, ptr, begin, begin_off)) {
- NANDBUS_UNLOCK(nandbus);
- return (ENXIO);
- }
-
- page++;
- ptr += begin;
- }
-
- while (num--) {
- if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
- NANDBUS_UNLOCK(nandbus);
- return (ENXIO);
- }
-
- page++;
- ptr += cg->page_size;
- }
-
- if (end)
- if (NAND_READ_PAGE(chip->dev, page, ptr, end, 0)) {
- NANDBUS_UNLOCK(nandbus);
- return (ENXIO);
- }
-
- NANDBUS_UNLOCK(nandbus);
-
- return (retval);
-}
-
-
-int
-nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf,
- uint32_t len)
-{
- struct chip_geom *cg;
- struct page_stat *pg_stat;
- struct nand_ecc_data *eccd;
- device_t nandbus;
- uint32_t page, num;
- uint8_t *oob = NULL;
- uint16_t *eccpos = NULL;
- int steps = 0, i, needwrite, err = 0;
-
- nand_debug(NDBG_NAND,"%p prog page %x[%x]", chip, offset, len);
-
- eccd = &chip->nand->ecc;
- cg = &chip->chip_geom;
- page = offset_to_page(cg, offset);
- num = len / cg->page_size;
-
- if (eccd->eccmode != NAND_ECC_NONE) {
- steps = cg->page_size / eccd->eccsize;
- oob = malloc(cg->oob_size, M_NAND, M_WAITOK);
- eccpos = default_software_ecc_positions(chip);
- }
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- while (num--) {
- if (NAND_PROGRAM_PAGE(chip->dev, page, buf, cg->page_size, 0)) {
- err = ENXIO;
- break;
- }
-
- if (eccd->eccmode != NAND_ECC_NONE) {
- if (NAND_GET_ECC(chip->dev, buf, &eccd->ecccalculated,
- &needwrite)) {
- err = ENXIO;
- break;
- }
- nand_debug(NDBG_ECC,"ECC calculated:");
- if (nand_debug_flag & NDBG_ECC)
- for (i = 0; i < (eccd->eccbytes * steps); i++)
- printf("%x ", eccd->ecccalculated[i]);
-
- nand_debug(NDBG_ECC,"\n");
-
- if (needwrite) {
- if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size,
- 0)) {
- err = ENXIO;
- break;
- }
-
- for (i = 0; i < (eccd->eccbytes * steps); i++)
- oob[eccpos[i]] = eccd->ecccalculated[i];
-
- if (NAND_PROGRAM_OOB(chip->dev, page, oob,
- cg->oob_size, 0)) {
- err = ENXIO;
- break;
- }
- }
- }
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_written++;
-
- page++;
- buf += cg->page_size;
- }
-
- NANDBUS_UNLOCK(nandbus);
-
- if (oob)
- free(oob, M_NAND);
-
- return (err);
-}
-
-int
-nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
- uint32_t len)
-{
- struct chip_geom *cg;
- device_t nandbus;
- uint8_t *ptr;
- uint32_t page, num, end, begin = 0, begin_off;
- int retval = 0;
-
- cg = &chip->chip_geom;
- page = offset_to_page(cg, offset);
- begin_off = offset - page * cg->page_size;
- if (begin_off) {
- begin = cg->page_size - begin_off;
- len -= begin;
- }
- num = len / cg->page_size;
- end = len % cg->page_size;
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- ptr = (uint8_t *)buf;
- if (begin_off) {
- if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, begin, begin_off)) {
- NANDBUS_UNLOCK(nandbus);
- return (ENXIO);
- }
-
- page++;
- ptr += begin;
- }
-
- while (num--) {
- if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, cg->page_size, 0)) {
- NANDBUS_UNLOCK(nandbus);
- return (ENXIO);
- }
-
- page++;
- ptr += cg->page_size;
- }
-
- if (end)
- retval = NAND_PROGRAM_PAGE(chip->dev, page, ptr, end, 0);
-
- NANDBUS_UNLOCK(nandbus);
-
- return (retval);
-}
-
-int
-nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf,
- uint32_t len)
-{
- device_t nandbus;
- int retval = 0;
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- retval = NAND_READ_OOB(chip->dev, page, buf, len, 0);
-
- NANDBUS_UNLOCK(nandbus);
-
- return (retval);
-}
-
-
-int
-nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf,
- uint32_t len)
-{
- device_t nandbus;
- int retval = 0;
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- retval = NAND_PROGRAM_OOB(chip->dev, page, buf, len, 0);
-
- NANDBUS_UNLOCK(nandbus);
-
- return (retval);
-}
-
-int
-nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len)
-{
- device_t nandbus;
- struct chip_geom *cg;
- uint32_t block, num_blocks;
- int err = 0;
-
- cg = &chip->chip_geom;
- if ((offset % cg->block_size) || (len % cg->block_size))
- return (EINVAL);
-
- block = offset / cg->block_size;
- num_blocks = len / cg->block_size;
- nand_debug(NDBG_NAND,"%p erase blocks %d[%d]", chip, block, num_blocks);
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- while (num_blocks--) {
- if (!nand_check_bad_block(chip, block)) {
- if (NAND_ERASE_BLOCK(chip->dev, block)) {
- nand_debug(NDBG_NAND,"%p erase blocks %d error",
- chip, block);
- nand_mark_bad_block(chip, block);
- err = ENXIO;
- }
- } else
- err = ENXIO;
-
- block++;
- }
-
- NANDBUS_UNLOCK(nandbus);
-
- if (err)
- nand_update_bbt(chip);
-
- return (err);
-}
-
-MODULE_VERSION(nand, 1);
diff --git a/sys/dev/nand/nand.h b/sys/dev/nand/nand.h
deleted file mode 100644
index 06902601b8d0..000000000000
--- a/sys/dev/nand/nand.h
+++ /dev/null
@@ -1,415 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _DEV_NAND_H_
-#define _DEV_NAND_H_
-
-#include <sys/bus.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/sx.h>
-#include <sys/taskqueue.h>
-#include <sys/queue.h>
-#include <sys/bio.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/malloc.h>
-
-#include <dev/nand/nand_dev.h>
-
-MALLOC_DECLARE(M_NAND);
-
-/* Read commands */
-#define NAND_CMD_READ 0x00
-#define NAND_CMD_CHNG_READ_COL 0x05
-#define NAND_CMD_READ_END 0x30
-#define NAND_CMD_READ_CACHE 0x31
-#define NAND_CMD_READ_CPBK 0x35
-#define NAND_CMD_READ_CACHE_END 0x3F
-#define NAND_CMD_CHNG_READ_COL_END 0xE0
-
-/* Erase commands */
-#define NAND_CMD_ERASE 0x60
-#define NAND_CMD_ERASE_END 0xD0
-#define NAND_CMD_ERASE_INTLV 0xD1
-
-/* Program commands */
-#define NAND_CMD_PROG 0x80
-#define NAND_CMD_CHNG_WRITE_COL 0x85
-#define NAND_CMD_PROG_END 0x10
-#define NAND_CMD_PROG_INTLV 0x11
-#define NAND_CMD_PROG_CACHE 0x15
-
-/* Misc commands */
-#define NAND_CMD_STATUS 0x70
-#define NAND_CMD_STATUS_ENH 0x78
-#define NAND_CMD_READ_ID 0x90
-#define NAND_CMD_READ_PARAMETER 0xec
-#define NAND_CMD_READ_UNIQUE_ID 0xed
-#define NAND_CMD_GET_FEATURE 0xee
-#define NAND_CMD_SET_FEATURE 0xef
-
-/* Reset commands */
-#define NAND_CMD_SYNCH_RESET 0xfc
-#define NAND_CMD_RESET 0xff
-
-/* Small page flash commands */
-#define NAND_CMD_SMALLA 0x00
-#define NAND_CMD_SMALLB 0x01
-#define NAND_CMD_SMALLOOB 0x50
-
-#define NAND_STATUS_FAIL 0x1
-#define NAND_STATUS_FAILC 0x2
-#define NAND_STATUS_ARDY 0x20
-#define NAND_STATUS_RDY 0x40
-#define NAND_STATUS_WP 0x80
-
-#define NAND_LP_OOB_COLUMN_START 0x800
-#define NAND_LP_OOBSZ 0x40
-#define NAND_SP_OOB_COLUMN_START 0x200
-#define NAND_SP_OOBSZ 0x10
-
-#define PAGE_PARAM_LENGTH 0x100
-#define PAGE_PARAMETER_DEF 0x0
-#define PAGE_PARAMETER_RED_1 0x100
-#define PAGE_PARAMETER_RED_2 0x200
-
-#define ONFI_SIG_ADDR 0x20
-
-#define NAND_MAX_CHIPS 0x4
-#define NAND_MAX_OOBSZ 512
-#define NAND_MAX_PAGESZ 16384
-
-#define NAND_SMALL_PAGE_SIZE 0x200
-
-#define NAND_16_BIT 0x00000001
-
-#define NAND_ECC_NONE 0x0
-#define NAND_ECC_SOFT 0x1
-#define NAND_ECC_FULLHW 0x2
-#define NAND_ECC_PARTHW 0x4
-#define NAND_ECC_MODE_MASK 0x7
-
-#define ECC_OK 0
-#define ECC_CORRECTABLE 1
-#define ECC_ERROR_ECC (-1)
-#define ECC_UNCORRECTABLE (-2)
-
-#define NAND_MAN_SAMSUNG 0xec
-#define NAND_MAN_HYNIX 0xad
-#define NAND_MAN_STMICRO 0x20
-#define NAND_MAN_MICRON 0x2c
-
-struct nand_id {
- uint8_t man_id;
- uint8_t dev_id;
-};
-
-struct nand_params {
- struct nand_id id;
- char *name;
- uint32_t chip_size;
- uint32_t page_size;
- uint32_t oob_size;
- uint32_t pages_per_block;
- uint32_t flags;
-};
-
-/* nand debug levels */
-#define NDBG_NAND 0x01
-#define NDBG_CDEV 0x02
-#define NDBG_GEN 0x04
-#define NDBG_GEOM 0x08
-#define NDBG_BUS 0x10
-#define NDBG_SIM 0x20
-#define NDBG_CTRL 0x40
-#define NDBG_DRV 0x80
-#define NDBG_ECC 0x100
-
-/* nand_debug_function */
-void nand_debug(int level, const char *fmt, ...);
-extern int nand_debug_flag;
-
-/* ONFI features bit*/
-#define ONFI_FEAT_16BIT 0x01
-#define ONFI_FEAT_MULT_LUN 0x02
-#define ONFI_FEAT_INTLV_OPS 0x04
-#define ONFI_FEAT_CPBK_RESTRICT 0x08
-#define ONFI_FEAT_SRC_SYNCH 0x10
-
-/* ONFI optional commands bits */
-#define ONFI_OPTCOM_PROG_CACHE 0x01
-#define ONFI_OPTCOM_READ_CACHE 0x02
-#define ONFI_OPTCOM_GETSET_FEAT 0x04
-#define ONFI_OPTCOM_STATUS_ENH 0x08
-#define ONFI_OPTCOM_COPYBACK 0x10
-#define ONFI_OPTCOM_UNIQUE_ID 0x20
-
-
-/* Layout of parameter page is defined in ONFI */
-struct onfi_params {
- char signature[4];
- uint16_t rev;
- uint16_t features;
- uint16_t optional_commands;
- uint8_t primary_advanced_command;
- uint8_t res1;
- uint16_t extended_parameter_page_length;
- uint8_t parameter_page_count;
- uint8_t res2[17];
- char manufacturer_name[12];
- char device_model[20];
- uint8_t manufacturer_id;
- uint8_t manufacture_date_yy;
- uint8_t manufacture_date_ww;
- uint8_t res3[13];
- uint32_t bytes_per_page;
- uint16_t spare_bytes_per_page;
- uint32_t bytes_per_partial_page;
- uint16_t spare_bytes_per_partial_page;
- uint32_t pages_per_block;
- uint32_t blocks_per_lun;
- uint8_t luns;
- uint8_t address_cycles;
- uint8_t bits_per_cell;
- uint16_t max_bad_block_per_lun;
- uint16_t block_endurance;
- uint8_t guaranteed_valid_blocks;
- uint16_t valid_block_endurance;
- uint8_t programs_per_page;
- uint8_t partial_prog_attr;
- uint8_t bits_of_ecc;
- uint8_t interleaved_addr_bits;
- uint8_t interleaved_oper_attr;
- uint8_t eznand_support;
- uint8_t res4[12];
- uint8_t pin_capacitance;
- uint16_t asynch_timing_mode_support;
- uint16_t asynch_prog_cache_timing_mode_support;
- uint16_t t_prog; /* us, max page program time */
- uint16_t t_bers; /* us, max block erase time */
- uint16_t t_r; /* us, max page read time */
- uint16_t t_ccs; /* ns, min change column setup time */
- uint16_t source_synch_timing_mode_support;
- uint8_t source_synch_feat;
- uint16_t clk_input_capacitance;
- uint16_t io_capacitance;
- uint16_t input_capacitance;
- uint8_t input_capacitance_max;
- uint8_t driver_strength_support;
- uint16_t t_r_interleaved;
- uint16_t t_adl;
- uint16_t t_r_eznand;
- uint8_t nv_ddr2_features;
- uint8_t nv_ddr2_warmup_cycles;
- uint8_t res5[4];
- uint16_t vendor_rev;
- uint8_t vendor_spec[88];
- uint16_t crc;
-}__attribute__((packed));
-CTASSERT(sizeof(struct onfi_params) == 256);
-
-struct onfi_chip_params {
- uint32_t blocks_per_lun;
- uint32_t pages_per_block;
- uint32_t bytes_per_page;
- uint32_t spare_bytes_per_page;
- uint16_t t_bers;
- uint16_t t_prog;
- uint16_t t_r;
- uint16_t t_ccs;
- uint16_t features;
- uint8_t address_cycles;
- uint8_t luns;
-};
-
-struct nand_ecc_data {
- int eccsize; /* Number of data bytes per ECC step */
- int eccmode;
- int eccbytes; /* Number of ECC bytes per step */
-
- uint16_t *eccpositions; /* Positions of ecc bytes */
- uint8_t ecccalculated[NAND_MAX_OOBSZ];
- uint8_t eccread[NAND_MAX_OOBSZ];
-};
-
-struct ecc_stat {
- uint32_t ecc_succeded;
- uint32_t ecc_corrected;
- uint32_t ecc_failed;
-};
-
-struct page_stat {
- struct ecc_stat ecc_stat;
- uint32_t page_read;
- uint32_t page_raw_read;
- uint32_t page_written;
- uint32_t page_raw_written;
-};
-
-struct block_stat {
- uint32_t block_erased;
-};
-
-struct chip_geom {
- uint32_t chip_size;
- uint32_t block_size;
- uint32_t page_size;
- uint32_t oob_size;
-
- uint32_t luns;
- uint32_t blks_per_lun;
- uint32_t blks_per_chip;
- uint32_t pgs_per_blk;
-
- uint32_t pg_mask;
- uint32_t blk_mask;
- uint32_t lun_mask;
- uint8_t blk_shift;
- uint8_t lun_shift;
-};
-
-struct nand_chip {
- device_t dev;
- struct nand_id id;
- struct chip_geom chip_geom;
-
- uint16_t t_prog; /* us, max page program time */
- uint16_t t_bers; /* us, max block erase time */
- uint16_t t_r; /* us, max page read time */
- uint16_t t_ccs; /* ns, min change column setup time */
- uint8_t num;
- uint8_t flags;
-
- struct page_stat *pg_stat;
- struct block_stat *blk_stat;
- struct nand_softc *nand;
- struct nand_bbt *bbt;
- struct nand_ops *ops;
- struct cdev *cdev;
-
- struct disk *ndisk;
- struct disk *rdisk;
- struct bio_queue_head bioq; /* bio queue */
- struct mtx qlock; /* bioq lock */
- struct taskqueue *tq; /* private task queue for i/o request */
- struct task iotask; /* i/o processing */
-
-};
-
-struct nand_softc {
- uint8_t flags;
-
- char *chip_cdev_name;
- struct nand_ecc_data ecc;
-};
-
-/* NAND ops */
-int nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len);
-int nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf,
- uint32_t len);
-int nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf,
- uint32_t len);
-int nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
- uint32_t len);
-int nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf,
- uint32_t len);
-int nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf,
- uint32_t len);
-int nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf,
- uint32_t len);
-
-int nand_select_cs(device_t dev, uint8_t cs);
-
-int nand_read_parameter(struct nand_softc *nand, struct onfi_params *param);
-int nand_synch_reset(struct nand_softc *nand);
-int nand_chng_read_col(device_t dev, uint32_t col, void *buf, size_t len);
-int nand_chng_write_col(device_t dev, uint32_t col, void *buf, size_t len);
-int nand_get_feature(device_t dev, uint8_t feat, void* buf);
-int nand_set_feature(device_t dev, uint8_t feat, void* buf);
-
-
-int nand_erase_block_intlv(device_t dev, uint32_t block);
-int nand_copyback_read(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len);
-int nand_copyback_prog(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len);
-int nand_copyback_prog_intlv(device_t dev, uint32_t page);
-int nand_prog_cache(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len, uint8_t end);
-int nand_prog_intlv(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len);
-int nand_read_cache(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len, uint8_t end);
-
-int nand_write_ecc(struct nand_softc *nand, uint32_t page, uint8_t *data);
-int nand_read_ecc(struct nand_softc *nand, uint32_t page, uint8_t *data);
-
-int nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc);
-int nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize,
- uint8_t *readecc, uint8_t *calcecc);
-
-/* Chip initialization */
-void nand_init(struct nand_softc *nand, device_t dev, int ecc_mode,
- int ecc_bytes, int ecc_size, uint16_t* eccposition, char* cdev_name);
-void nand_detach(struct nand_softc *nand);
-struct nand_params *nand_get_params(struct nand_id *id);
-
-void nand_onfi_set_params(struct nand_chip *chip, struct onfi_chip_params *params);
-void nand_set_params(struct nand_chip *chip, struct nand_params *params);
-int nand_init_stat(struct nand_chip *chip);
-void nand_destroy_stat(struct nand_chip *chip);
-
-/* BBT */
-int nand_init_bbt(struct nand_chip *chip);
-void nand_destroy_bbt(struct nand_chip *chip);
-int nand_update_bbt(struct nand_chip *chip);
-int nand_mark_bad_block(struct nand_chip* chip, uint32_t block_num);
-int nand_check_bad_block(struct nand_chip* chip, uint32_t block_num);
-
-/* cdev creation/removal */
-int nand_make_dev(struct nand_chip* chip);
-void nand_destroy_dev(struct nand_chip *chip);
-
-int create_geom_disk(struct nand_chip* chip);
-int create_geom_raw_disk(struct nand_chip *chip);
-void destroy_geom_disk(struct nand_chip *chip);
-void destroy_geom_raw_disk(struct nand_chip *chip);
-
-int init_chip_geom(struct chip_geom* cg, uint32_t luns, uint32_t blks_per_lun,
- uint32_t pgs_per_blk, uint32_t pg_size, uint32_t oob_size);
-int nand_row_to_blkpg(struct chip_geom *cg, uint32_t row, uint32_t *lun,
- uint32_t *blk, uint32_t *pg);
-int page_to_row(struct chip_geom *cg, uint32_t page, uint32_t *row);
-int nand_check_page_boundary(struct nand_chip *chip, uint32_t page);
-void nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param);
-
-#endif /* _DEV_NAND_H_ */
diff --git a/sys/dev/nand/nand_bbt.c b/sys/dev/nand/nand_bbt.c
deleted file mode 100644
index d99ed67523a2..000000000000
--- a/sys/dev/nand/nand_bbt.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-
-#include <dev/nand/nand.h>
-
-#include "nand_if.h"
-
-#define BBT_PRIMARY_PATTERN 0x01020304
-#define BBT_SECONDARY_PATTERN 0x05060708
-
-enum bbt_place {
- BBT_NONE,
- BBT_PRIMARY,
- BBT_SECONDARY
-};
-
-struct nand_bbt {
- struct nand_chip *chip;
- uint32_t primary_map;
- uint32_t secondary_map;
- enum bbt_place active;
- struct bbt_header *hdr;
- uint32_t tab_len;
- uint32_t *table;
-};
-
-struct bbt_header {
- uint32_t pattern;
- int32_t seq_nr;
-};
-
-static int nand_bbt_save(struct nand_bbt *);
-static int nand_bbt_load_hdr(struct nand_bbt *, struct bbt_header *, int8_t);
-static int nand_bbt_load_table(struct nand_bbt *);
-static int nand_bbt_prescan(struct nand_bbt *);
-
-int
-nand_init_bbt(struct nand_chip *chip)
-{
- struct chip_geom *cg;
- struct nand_bbt *bbt;
- int err;
-
- cg = &chip->chip_geom;
-
- bbt = malloc(sizeof(struct nand_bbt), M_NAND, M_ZERO | M_WAITOK);
- if (!bbt) {
- device_printf(chip->dev,
- "Cannot allocate memory for bad block struct");
- return (ENOMEM);
- }
-
- bbt->chip = chip;
- bbt->active = BBT_NONE;
- bbt->primary_map = cg->chip_size - cg->block_size;
- bbt->secondary_map = cg->chip_size - 2 * cg->block_size;
- bbt->tab_len = cg->blks_per_chip * sizeof(uint32_t);
- bbt->hdr = malloc(sizeof(struct bbt_header) + bbt->tab_len, M_NAND,
- M_WAITOK);
- if (!bbt->hdr) {
- device_printf(chip->dev, "Cannot allocate %d bytes for BB "
- "Table", bbt->tab_len);
- free(bbt, M_NAND);
- return (ENOMEM);
- }
- bbt->hdr->seq_nr = 0;
- bbt->table = (uint32_t *)((uint8_t *)bbt->hdr +
- sizeof(struct bbt_header));
-
- err = nand_bbt_load_table(bbt);
- if (err) {
- free(bbt->table, M_NAND);
- free(bbt, M_NAND);
- return (err);
- }
-
- chip->bbt = bbt;
- if (bbt->active == BBT_NONE) {
- bbt->active = BBT_PRIMARY;
- memset(bbt->table, 0xff, bbt->tab_len);
- nand_bbt_prescan(bbt);
- nand_bbt_save(bbt);
- } else
- device_printf(chip->dev, "Found BBT table for chip\n");
-
- return (0);
-}
-
-void
-nand_destroy_bbt(struct nand_chip *chip)
-{
-
- if (chip->bbt) {
- nand_bbt_save(chip->bbt);
-
- free(chip->bbt->hdr, M_NAND);
- free(chip->bbt, M_NAND);
- chip->bbt = NULL;
- }
-}
-
-int
-nand_update_bbt(struct nand_chip *chip)
-{
-
- nand_bbt_save(chip->bbt);
-
- return (0);
-}
-
-static int
-nand_bbt_save(struct nand_bbt *bbt)
-{
- enum bbt_place next;
- uint32_t addr;
- int32_t err;
-
- if (bbt->active == BBT_PRIMARY) {
- addr = bbt->secondary_map;
- bbt->hdr->pattern = BBT_SECONDARY_PATTERN;
- next = BBT_SECONDARY;
- } else {
- addr = bbt->primary_map;
- bbt->hdr->pattern = BBT_PRIMARY_PATTERN;
- next = BBT_PRIMARY;
- }
-
- err = nand_erase_blocks(bbt->chip, addr,
- bbt->chip->chip_geom.block_size);
- if (err)
- return (err);
-
- bbt->hdr->seq_nr++;
-
- err = nand_prog_pages_raw(bbt->chip, addr, bbt->hdr,
- bbt->tab_len + sizeof(struct bbt_header));
- if (err)
- return (err);
-
- bbt->active = next;
- return (0);
-}
-
-static int
-nand_bbt_load_hdr(struct nand_bbt *bbt, struct bbt_header *hdr, int8_t primary)
-{
- uint32_t addr;
-
- if (primary)
- addr = bbt->primary_map;
- else
- addr = bbt->secondary_map;
-
- return (nand_read_pages_raw(bbt->chip, addr, hdr,
- sizeof(struct bbt_header)));
-}
-
-static int
-nand_bbt_load_table(struct nand_bbt *bbt)
-{
- struct bbt_header hdr1, hdr2;
- uint32_t address = 0;
- int err = 0;
-
- bzero(&hdr1, sizeof(hdr1));
- bzero(&hdr2, sizeof(hdr2));
-
- nand_bbt_load_hdr(bbt, &hdr1, 1);
- if (hdr1.pattern == BBT_PRIMARY_PATTERN) {
- bbt->active = BBT_PRIMARY;
- address = bbt->primary_map;
- } else
- bzero(&hdr1, sizeof(hdr1));
-
-
- nand_bbt_load_hdr(bbt, &hdr2, 0);
- if ((hdr2.pattern == BBT_SECONDARY_PATTERN) &&
- (hdr2.seq_nr > hdr1.seq_nr)) {
- bbt->active = BBT_SECONDARY;
- address = bbt->secondary_map;
- } else
- bzero(&hdr2, sizeof(hdr2));
-
- if (bbt->active != BBT_NONE)
- err = nand_read_pages_raw(bbt->chip, address, bbt->hdr,
- bbt->tab_len + sizeof(struct bbt_header));
-
- return (err);
-}
-
-static int
-nand_bbt_prescan(struct nand_bbt *bbt)
-{
- int32_t i;
- uint8_t bad;
- bool printed_hash = 0;
-
- device_printf(bbt->chip->dev, "No BBT found. Prescan chip...\n");
- for (i = 0; i < bbt->chip->chip_geom.blks_per_chip; i++) {
- if (NAND_IS_BLK_BAD(bbt->chip->dev, i, &bad))
- return (ENXIO);
-
- if (bad) {
- device_printf(bbt->chip->dev, "Bad block(%d)\n", i);
- bbt->table[i] = 0x0FFFFFFF;
- }
- if (!(i % 100)) {
- printf("#");
- printed_hash = 1;
- }
- }
-
- if (printed_hash)
- printf("\n");
-
- return (0);
-}
-
-int
-nand_check_bad_block(struct nand_chip *chip, uint32_t block_number)
-{
-
- if (!chip || !chip->bbt)
- return (0);
-
- if ((chip->bbt->table[block_number] & 0xF0000000) == 0)
- return (1);
-
- return (0);
-}
-
-int
-nand_mark_bad_block(struct nand_chip *chip, uint32_t block_number)
-{
-
- chip->bbt->table[block_number] = 0x0FFFFFFF;
-
- return (0);
-}
diff --git a/sys/dev/nand/nand_cdev.c b/sys/dev/nand/nand_cdev.c
deleted file mode 100644
index 53c62dbc2913..000000000000
--- a/sys/dev/nand/nand_cdev.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-#include <sys/uio.h>
-#include <sys/bio.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-#include <dev/nand/nand_dev.h>
-#include "nand_if.h"
-#include "nandbus_if.h"
-
-static int nand_page_stat(struct nand_chip *, struct page_stat_io *);
-static int nand_block_stat(struct nand_chip *, struct block_stat_io *);
-
-static d_ioctl_t nand_ioctl;
-static d_open_t nand_open;
-static d_strategy_t nand_strategy;
-
-static struct cdevsw nand_cdevsw = {
- .d_version = D_VERSION,
- .d_name = "nand",
- .d_open = nand_open,
- .d_read = physread,
- .d_write = physwrite,
- .d_ioctl = nand_ioctl,
- .d_strategy = nand_strategy,
-};
-
-static int
-offset_to_page(struct chip_geom *cg, uint32_t offset)
-{
-
- return (offset / cg->page_size);
-}
-
-static int
-offset_to_page_off(struct chip_geom *cg, uint32_t offset)
-{
-
- return (offset % cg->page_size);
-}
-
-int
-nand_make_dev(struct nand_chip *chip)
-{
- struct nandbus_ivar *ivar;
- device_t parent, nandbus;
- int parent_unit, unit;
- char *name;
-
- ivar = device_get_ivars(chip->dev);
- nandbus = device_get_parent(chip->dev);
-
- if (ivar->chip_cdev_name) {
- name = ivar->chip_cdev_name;
-
- /*
- * If we got distinct name for chip device we can enumarete it
- * based on contoller number.
- */
- parent = device_get_parent(nandbus);
- } else {
- name = "nand";
- parent = nandbus;
- }
-
- parent_unit = device_get_unit(parent);
- unit = parent_unit * 4 + chip->num;
- chip->cdev = make_dev(&nand_cdevsw, unit, UID_ROOT, GID_WHEEL,
- 0666, "%s%d.%d", name, parent_unit, chip->num);
-
- if (chip->cdev == NULL)
- return (ENXIO);
-
- if (bootverbose)
- device_printf(chip->dev, "Created cdev %s%d.%d for chip "
- "[0x%0x, 0x%0x]\n", name, parent_unit, chip->num,
- ivar->man_id, ivar->dev_id);
-
- chip->cdev->si_drv1 = chip;
-
- return (0);
-}
-
-void
-nand_destroy_dev(struct nand_chip *chip)
-{
-
- if (chip->cdev)
- destroy_dev(chip->cdev);
-}
-
-static int
-nand_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
-{
-
- return (0);
-}
-
-static int
-nand_read(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len)
-{
- struct chip_geom *cg;
- device_t nandbus;
- int start_page, count, off, err = 0;
- uint8_t *ptr, *tmp;
-
- nand_debug(NDBG_CDEV, "Read from chip%d [%p] at %d\n", chip->num,
- chip, offset);
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- cg = &chip->chip_geom;
- start_page = offset_to_page(cg, offset);
- off = offset_to_page_off(cg, offset);
- count = (len > cg->page_size - off) ? cg->page_size - off : len;
-
- ptr = (uint8_t *)buf;
- while (len > 0) {
- if (len < cg->page_size) {
- tmp = malloc(cg->page_size, M_NAND, M_WAITOK);
- if (!tmp) {
- err = ENOMEM;
- break;
- }
- err = NAND_READ_PAGE(chip->dev, start_page,
- tmp, cg->page_size, 0);
- if (err) {
- free(tmp, M_NAND);
- break;
- }
- bcopy(tmp + off, ptr, count);
- free(tmp, M_NAND);
- } else {
- err = NAND_READ_PAGE(chip->dev, start_page,
- ptr, cg->page_size, 0);
- if (err)
- break;
- }
-
- len -= count;
- start_page++;
- ptr += count;
- count = (len > cg->page_size) ? cg->page_size : len;
- off = 0;
- }
-
- NANDBUS_UNLOCK(nandbus);
- return (err);
-}
-
-static int
-nand_write(struct nand_chip *chip, uint32_t offset, void* buf, uint32_t len)
-{
- struct chip_geom *cg;
- device_t nandbus;
- int off, start_page, err = 0;
- uint8_t *ptr;
-
- nand_debug(NDBG_CDEV, "Write to chip %d [%p] at %d\n", chip->num,
- chip, offset);
-
- nandbus = device_get_parent(chip->dev);
- NANDBUS_LOCK(nandbus);
- NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num);
-
- cg = &chip->chip_geom;
- start_page = offset_to_page(cg, offset);
- off = offset_to_page_off(cg, offset);
-
- if (off != 0 || (len % cg->page_size) != 0) {
- printf("Not aligned write start [0x%08x] size [0x%08x]\n",
- off, len);
- NANDBUS_UNLOCK(nandbus);
- return (EINVAL);
- }
-
- ptr = (uint8_t *)buf;
- while (len > 0) {
- err = NAND_PROGRAM_PAGE(chip->dev, start_page, ptr,
- cg->page_size, 0);
- if (err)
- break;
-
- len -= cg->page_size;
- start_page++;
- ptr += cg->page_size;
- }
-
- NANDBUS_UNLOCK(nandbus);
- return (err);
-}
-
-static void
-nand_strategy(struct bio *bp)
-{
- struct nand_chip *chip;
- struct cdev *dev;
- int err = 0;
-
- dev = bp->bio_dev;
- chip = dev->si_drv1;
-
- nand_debug(NDBG_CDEV, "Strategy %s on chip %d [%p]\n",
- bp->bio_cmd == BIO_READ ? "READ" : "WRITE",
- chip->num, chip);
-
- if (bp->bio_cmd == BIO_READ) {
- err = nand_read(chip,
- bp->bio_offset & 0xffffffff,
- bp->bio_data, bp->bio_bcount);
- } else {
- err = nand_write(chip,
- bp->bio_offset & 0xffffffff,
- bp->bio_data, bp->bio_bcount);
- }
-
- if (err == 0)
- bp->bio_resid = 0;
- else {
- bp->bio_error = EIO;
- bp->bio_flags |= BIO_ERROR;
- bp->bio_resid = bp->bio_bcount;
- }
-
- biodone(bp);
-}
-
-static int
-nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset,
- uint32_t len, uint8_t *data, uint8_t write)
-{
- struct chip_geom *cg;
- uint8_t *buf = NULL;
- int ret = 0;
-
- cg = &chip->chip_geom;
-
- buf = malloc(cg->oob_size, M_NAND, M_WAITOK);
- if (!buf)
- return (ENOMEM);
-
- memset(buf, 0xff, cg->oob_size);
-
- if (!write) {
- ret = nand_read_oob(chip, page, buf, cg->oob_size);
- copyout(buf, data, len);
- } else {
- copyin(data, buf, len);
- ret = nand_prog_oob(chip, page, buf, cg->oob_size);
- }
-
- free(buf, M_NAND);
-
- return (ret);
-}
-
-static int
-nand_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
- struct thread *td)
-{
- struct nand_chip *chip;
- struct chip_geom *cg;
- struct nand_oob_rw *oob_rw = NULL;
- struct nand_raw_rw *raw_rw = NULL;
- device_t nandbus;
- size_t bufsize = 0, len = 0;
- size_t raw_size;
- off_t off;
- uint8_t *buf = NULL;
- int ret = 0;
- uint8_t status;
-
- chip = (struct nand_chip *)dev->si_drv1;
- cg = &chip->chip_geom;
- nandbus = device_get_parent(chip->dev);
-
- if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) {
- raw_rw = (struct nand_raw_rw *)data;
- raw_size = cg->pgs_per_blk * (cg->page_size + cg->oob_size);
-
- /* Check if len is not bigger than chip size */
- if (raw_rw->len > raw_size)
- return (EFBIG);
-
- /*
- * Do not ask for too much memory, in case of large transfers
- * read/write in 16-pages chunks
- */
- bufsize = 16 * (cg->page_size + cg->oob_size);
- if (raw_rw->len < bufsize)
- bufsize = raw_rw->len;
-
- buf = malloc(bufsize, M_NAND, M_WAITOK);
- len = raw_rw->len;
- off = 0;
- }
- switch(cmd) {
- case NAND_IO_ERASE:
- ret = nand_erase_blocks(chip, ((off_t *)data)[0],
- ((off_t *)data)[1]);
- break;
-
- case NAND_IO_OOB_READ:
- oob_rw = (struct nand_oob_rw *)data;
- ret = nand_oob_access(chip, oob_rw->page, 0,
- oob_rw->len, oob_rw->data, 0);
- break;
-
- case NAND_IO_OOB_PROG:
- oob_rw = (struct nand_oob_rw *)data;
- ret = nand_oob_access(chip, oob_rw->page, 0,
- oob_rw->len, oob_rw->data, 1);
- break;
-
- case NAND_IO_GET_STATUS:
- NANDBUS_LOCK(nandbus);
- ret = NANDBUS_GET_STATUS(nandbus, &status);
- if (ret == 0)
- *(uint8_t *)data = status;
- NANDBUS_UNLOCK(nandbus);
- break;
-
- case NAND_IO_RAW_PROG:
- while (len > 0) {
- if (len < bufsize)
- bufsize = len;
- ret = copyin(raw_rw->data + off, buf, bufsize);
- if (ret)
- break;
- ret = nand_prog_pages_raw(chip, raw_rw->off + off, buf,
- bufsize);
- if (ret)
- break;
- len -= bufsize;
- off += bufsize;
- }
- break;
-
- case NAND_IO_RAW_READ:
- while (len > 0) {
- if (len < bufsize)
- bufsize = len;
-
- ret = nand_read_pages_raw(chip, raw_rw->off + off, buf,
- bufsize);
- if (ret)
- break;
-
- ret = copyout(buf, raw_rw->data + off, bufsize);
- if (ret)
- break;
- len -= bufsize;
- off += bufsize;
- }
- break;
-
- case NAND_IO_PAGE_STAT:
- ret = nand_page_stat(chip, (struct page_stat_io *)data);
- break;
-
- case NAND_IO_BLOCK_STAT:
- ret = nand_block_stat(chip, (struct block_stat_io *)data);
- break;
-
- case NAND_IO_GET_CHIP_PARAM:
- nand_get_chip_param(chip, (struct chip_param_io *)data);
- break;
-
- default:
- printf("Unknown nand_ioctl request \n");
- ret = EIO;
- }
-
- if (buf)
- free(buf, M_NAND);
-
- return (ret);
-}
-
-static int
-nand_page_stat(struct nand_chip *chip, struct page_stat_io *page_stat)
-{
- struct chip_geom *cg;
- struct page_stat *stat;
- int num_pages;
-
- cg = &chip->chip_geom;
- num_pages = cg->pgs_per_blk * cg->blks_per_lun * cg->luns;
- if (page_stat->page_num >= num_pages)
- return (EINVAL);
-
- stat = &chip->pg_stat[page_stat->page_num];
- page_stat->page_read = stat->page_read;
- page_stat->page_written = stat->page_written;
- page_stat->page_raw_read = stat->page_raw_read;
- page_stat->page_raw_written = stat->page_raw_written;
- page_stat->ecc_succeded = stat->ecc_stat.ecc_succeded;
- page_stat->ecc_corrected = stat->ecc_stat.ecc_corrected;
- page_stat->ecc_failed = stat->ecc_stat.ecc_failed;
-
- return (0);
-}
-
-static int
-nand_block_stat(struct nand_chip *chip, struct block_stat_io *block_stat)
-{
- struct chip_geom *cg;
- uint32_t block_num = block_stat->block_num;
-
- cg = &chip->chip_geom;
- if (block_num >= cg->blks_per_lun * cg->luns)
- return (EINVAL);
-
- block_stat->block_erased = chip->blk_stat[block_num].block_erased;
-
- return (0);
-}
diff --git a/sys/dev/nand/nand_dev.h b/sys/dev/nand/nand_dev.h
deleted file mode 100644
index bd00c4d4b3b4..000000000000
--- a/sys/dev/nand/nand_dev.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _DEV_NAND_CDEV_H_
-#define _DEV_NAND_CDEV_H_
-
-#include <sys/ioccom.h>
-#include <sys/param.h>
-
-struct nand_raw_rw {
- off_t off;
- off_t len;
- uint8_t *data;
-};
-
-struct nand_oob_rw {
- uint32_t page;
- off_t len;
- uint8_t *data;
-};
-
-#define NAND_IOCTL_GROUP 'N'
-#define NAND_IO_ERASE _IOWR(NAND_IOCTL_GROUP, 0x0, off_t[2])
-
-#define NAND_IO_OOB_READ _IOWR(NAND_IOCTL_GROUP, 0x1, struct nand_oob_rw)
-
-#define NAND_IO_OOB_PROG _IOWR(NAND_IOCTL_GROUP, 0x2, struct nand_oob_rw)
-
-#define NAND_IO_RAW_READ _IOWR(NAND_IOCTL_GROUP, 0x3, struct nand_raw_rw)
-
-#define NAND_IO_RAW_PROG _IOWR(NAND_IOCTL_GROUP, 0x4, struct nand_raw_rw)
-
-#define NAND_IO_GET_STATUS _IOWR(NAND_IOCTL_GROUP, 0x5, uint8_t)
-
-struct page_stat_io {
- uint32_t page_num;
- uint32_t page_read;
- uint32_t page_written;
- uint32_t page_raw_read;
- uint32_t page_raw_written;
- uint32_t ecc_succeded;
- uint32_t ecc_corrected;
- uint32_t ecc_failed;
-};
-#define NAND_IO_PAGE_STAT _IOWR(NAND_IOCTL_GROUP, 0x6, \
- struct page_stat_io)
-
-struct block_stat_io {
- uint32_t block_num;
- uint32_t block_erased;
-};
-#define NAND_IO_BLOCK_STAT _IOWR(NAND_IOCTL_GROUP, 0x7, \
- struct block_stat_io)
-
-struct chip_param_io {
- uint32_t page_size;
- uint32_t oob_size;
-
- uint32_t blocks;
- uint32_t pages_per_block;
-};
-#define NAND_IO_GET_CHIP_PARAM _IOWR(NAND_IOCTL_GROUP, 0x8, \
- struct chip_param_io)
-
-#endif /* _DEV_NAND_CDEV_H_ */
diff --git a/sys/dev/nand/nand_ecc_pos.h b/sys/dev/nand/nand_ecc_pos.h
deleted file mode 100644
index 835f45e6c083..000000000000
--- a/sys/dev/nand/nand_ecc_pos.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _DEV_NAND_ECC_POS_H_
-#define _DEV_NAND_ECC_POS_H_
-
-static uint16_t default_software_ecc_positions_16[] = {2, 0, 1, 7, 4, 6};
-
-static uint16_t default_software_ecc_positions_64[] = {
-
- 42, 40, 41, 45, 43, 44, 48, 46,
- 47, 51, 49, 50, 54, 52, 53, 57,
- 55, 56, 60, 58, 59, 63, 61, 62
-};
-
-static uint16_t default_software_ecc_positions_128[] = {
- 8, 9, 10, 11, 12, 13,
- 18, 19, 20, 21, 22, 23,
- 28, 29, 30, 31, 32, 33,
- 38, 39, 40, 41, 42, 43,
- 48, 49, 50, 51, 52, 53,
- 58, 59, 60, 61, 62, 63,
- 68, 69, 70, 71, 72, 73,
- 78, 79, 80, 81, 82, 83,
- 88, 89, 90, 91, 92, 93,
- 98, 99, 100, 101, 102, 103,
- 108, 109, 110, 111, 112, 113,
- 118, 119, 120, 121, 122, 123,
-};
-#endif /* _DEV_NAND_ECC_POS_H_ */
-
diff --git a/sys/dev/nand/nand_generic.c b/sys/dev/nand/nand_generic.c
deleted file mode 100644
index cc6ef9bd57b0..000000000000
--- a/sys/dev/nand/nand_generic.c
+++ /dev/null
@@ -1,1366 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-/* Generic NAND driver */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/endian.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/time.h>
-#include <sys/malloc.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-#include "nfc_if.h"
-#include "nand_if.h"
-#include "nandbus_if.h"
-
-
-static int onfi_nand_probe(device_t dev);
-static int large_nand_probe(device_t dev);
-static int small_nand_probe(device_t dev);
-static int generic_nand_attach(device_t dev);
-static int generic_nand_detach(device_t dev);
-
-static int generic_erase_block(device_t, uint32_t);
-static int generic_erase_block_intlv(device_t, uint32_t);
-static int generic_read_page (device_t, uint32_t, void *, uint32_t, uint32_t);
-static int generic_read_oob(device_t, uint32_t, void *, uint32_t, uint32_t);
-static int generic_program_page(device_t, uint32_t, void *, uint32_t, uint32_t);
-static int generic_program_page_intlv(device_t, uint32_t, void *, uint32_t,
- uint32_t);
-static int generic_program_oob(device_t, uint32_t, void *, uint32_t, uint32_t);
-static int generic_is_blk_bad(device_t, uint32_t, uint8_t *);
-static int generic_get_ecc(device_t, void *, void *, int *);
-static int generic_correct_ecc(device_t, void *, void *, void *);
-
-static int small_read_page(device_t, uint32_t, void *, uint32_t, uint32_t);
-static int small_read_oob(device_t, uint32_t, void *, uint32_t, uint32_t);
-static int small_program_page(device_t, uint32_t, void *, uint32_t, uint32_t);
-static int small_program_oob(device_t, uint32_t, void *, uint32_t, uint32_t);
-
-static int onfi_is_blk_bad(device_t, uint32_t, uint8_t *);
-static int onfi_read_parameter(struct nand_chip *, struct onfi_chip_params *);
-
-static int nand_send_address(device_t, int32_t, int32_t, int8_t);
-
-static device_method_t onand_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, onfi_nand_probe),
- DEVMETHOD(device_attach, generic_nand_attach),
- DEVMETHOD(device_detach, generic_nand_detach),
-
- DEVMETHOD(nand_read_page, generic_read_page),
- DEVMETHOD(nand_program_page, generic_program_page),
- DEVMETHOD(nand_program_page_intlv, generic_program_page_intlv),
- DEVMETHOD(nand_read_oob, generic_read_oob),
- DEVMETHOD(nand_program_oob, generic_program_oob),
- DEVMETHOD(nand_erase_block, generic_erase_block),
- DEVMETHOD(nand_erase_block_intlv, generic_erase_block_intlv),
-
- DEVMETHOD(nand_is_blk_bad, onfi_is_blk_bad),
- DEVMETHOD(nand_get_ecc, generic_get_ecc),
- DEVMETHOD(nand_correct_ecc, generic_correct_ecc),
- { 0, 0 }
-};
-
-static device_method_t lnand_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, large_nand_probe),
- DEVMETHOD(device_attach, generic_nand_attach),
- DEVMETHOD(device_detach, generic_nand_detach),
-
- DEVMETHOD(nand_read_page, generic_read_page),
- DEVMETHOD(nand_program_page, generic_program_page),
- DEVMETHOD(nand_read_oob, generic_read_oob),
- DEVMETHOD(nand_program_oob, generic_program_oob),
- DEVMETHOD(nand_erase_block, generic_erase_block),
-
- DEVMETHOD(nand_is_blk_bad, generic_is_blk_bad),
- DEVMETHOD(nand_get_ecc, generic_get_ecc),
- DEVMETHOD(nand_correct_ecc, generic_correct_ecc),
- { 0, 0 }
-};
-
-static device_method_t snand_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, small_nand_probe),
- DEVMETHOD(device_attach, generic_nand_attach),
- DEVMETHOD(device_detach, generic_nand_detach),
-
- DEVMETHOD(nand_read_page, small_read_page),
- DEVMETHOD(nand_program_page, small_program_page),
- DEVMETHOD(nand_read_oob, small_read_oob),
- DEVMETHOD(nand_program_oob, small_program_oob),
- DEVMETHOD(nand_erase_block, generic_erase_block),
-
- DEVMETHOD(nand_is_blk_bad, generic_is_blk_bad),
- DEVMETHOD(nand_get_ecc, generic_get_ecc),
- DEVMETHOD(nand_correct_ecc, generic_correct_ecc),
- { 0, 0 }
-};
-
-devclass_t onand_devclass;
-devclass_t lnand_devclass;
-devclass_t snand_devclass;
-
-driver_t onand_driver = {
- "onand",
- onand_methods,
- sizeof(struct nand_chip)
-};
-
-driver_t lnand_driver = {
- "lnand",
- lnand_methods,
- sizeof(struct nand_chip)
-};
-
-driver_t snand_driver = {
- "snand",
- snand_methods,
- sizeof(struct nand_chip)
-};
-
-DRIVER_MODULE(onand, nandbus, onand_driver, onand_devclass, 0, 0);
-DRIVER_MODULE(lnand, nandbus, lnand_driver, lnand_devclass, 0, 0);
-DRIVER_MODULE(snand, nandbus, snand_driver, snand_devclass, 0, 0);
-
-static int
-onfi_nand_probe(device_t dev)
-{
- struct nandbus_ivar *ivar;
-
- ivar = device_get_ivars(dev);
- if (ivar && ivar->is_onfi) {
- device_set_desc(dev, "ONFI compliant NAND");
- return (BUS_PROBE_DEFAULT);
- }
-
- return (ENODEV);
-}
-
-static int
-large_nand_probe(device_t dev)
-{
- struct nandbus_ivar *ivar;
-
- ivar = device_get_ivars(dev);
- if (ivar && !ivar->is_onfi && ivar->params->page_size >= 512) {
- device_set_desc(dev, ivar->params->name);
- return (BUS_PROBE_DEFAULT);
- }
-
- return (ENODEV);
-}
-
-static int
-small_nand_probe(device_t dev)
-{
- struct nandbus_ivar *ivar;
-
- ivar = device_get_ivars(dev);
- if (ivar && !ivar->is_onfi && ivar->params->page_size == 512) {
- device_set_desc(dev, ivar->params->name);
- return (BUS_PROBE_DEFAULT);
- }
-
- return (ENODEV);
-}
-
-static int
-generic_nand_attach(device_t dev)
-{
- struct nand_chip *chip;
- struct nandbus_ivar *ivar;
- struct onfi_chip_params *onfi_chip_params;
- device_t nandbus, nfc;
- int err;
-
- chip = device_get_softc(dev);
- chip->dev = dev;
-
- ivar = device_get_ivars(dev);
- chip->id.man_id = ivar->man_id;
- chip->id.dev_id = ivar->dev_id;
- chip->num = ivar->cs;
-
- /* TODO remove when HW ECC supported */
- nandbus = device_get_parent(dev);
- nfc = device_get_parent(nandbus);
-
- chip->nand = device_get_softc(nfc);
-
- if (ivar->is_onfi) {
- onfi_chip_params = malloc(sizeof(struct onfi_chip_params),
- M_NAND, M_WAITOK | M_ZERO);
-
- if (onfi_read_parameter(chip, onfi_chip_params)) {
- nand_debug(NDBG_GEN,"Could not read parameter page!\n");
- free(onfi_chip_params, M_NAND);
- return (ENXIO);
- }
-
- nand_onfi_set_params(chip, onfi_chip_params);
- /* Set proper column and row cycles */
- ivar->cols = (onfi_chip_params->address_cycles >> 4) & 0xf;
- ivar->rows = onfi_chip_params->address_cycles & 0xf;
- free(onfi_chip_params, M_NAND);
-
- } else {
- nand_set_params(chip, ivar->params);
- }
-
- err = nand_init_stat(chip);
- if (err) {
- generic_nand_detach(dev);
- return (err);
- }
-
- err = nand_init_bbt(chip);
- if (err) {
- generic_nand_detach(dev);
- return (err);
- }
-
- err = nand_make_dev(chip);
- if (err) {
- generic_nand_detach(dev);
- return (err);
- }
-
- err = create_geom_disk(chip);
- if (err) {
- generic_nand_detach(dev);
- return (err);
- }
-
- return (0);
-}
-
-static int
-generic_nand_detach(device_t dev)
-{
- struct nand_chip *chip;
-
- chip = device_get_softc(dev);
-
- nand_destroy_bbt(chip);
- destroy_geom_disk(chip);
- nand_destroy_dev(chip);
- nand_destroy_stat(chip);
-
- return (0);
-}
-
-static int
-can_write(device_t nandbus)
-{
- uint8_t status;
-
- if (NANDBUS_WAIT_READY(nandbus, &status))
- return (0);
-
- if (!(status & NAND_STATUS_WP)) {
- nand_debug(NDBG_GEN,"Chip is write-protected");
- return (0);
- }
-
- return (1);
-}
-
-static int
-check_fail(device_t nandbus)
-{
- uint8_t status;
-
- NANDBUS_WAIT_READY(nandbus, &status);
- if (status & NAND_STATUS_FAIL) {
- nand_debug(NDBG_GEN,"Status failed %x", status);
- return (ENXIO);
- }
-
- return (0);
-}
-
-static uint16_t
-onfi_crc(const void *buf, size_t buflen)
-{
- int i, j;
- uint16_t crc;
- const uint8_t *bufptr;
-
- bufptr = buf;
- crc = 0x4f4e;
- for (j = 0; j < buflen; j++) {
- crc ^= *bufptr++ << 8;
- for (i = 0; i < 8; i++)
- if (crc & 0x8000)
- crc = (crc << 1) ^ 0x8005;
- else
- crc <<= 1;
- }
- return crc;
-}
-
-static int
-onfi_read_parameter(struct nand_chip *chip, struct onfi_chip_params *chip_params)
-{
- device_t nandbus;
- struct onfi_params params;
- int found, sigcount, trycopy;
-
- nand_debug(NDBG_GEN,"read parameter");
-
- nandbus = device_get_parent(chip->dev);
-
- NANDBUS_SELECT_CS(nandbus, chip->num);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_READ_PARAMETER))
- return (ENXIO);
-
- if (nand_send_address(chip->dev, -1, -1, PAGE_PARAMETER_DEF))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- /*
- * XXX Bogus DELAY, we really need a nandbus_wait_ready() here, but it's
- * not accessible from here (static to nandbus).
- */
- DELAY(1000);
-
- /*
- * The ONFI spec mandates a minimum of three copies of the parameter
- * data, so loop up to 3 times trying to find good data. Each copy is
- * validated by a signature of "ONFI" and a crc. There is a very strange
- * rule that the signature is valid if any 2 of the 4 bytes are correct.
- */
- for (found= 0, trycopy = 0; !found && trycopy < 3; trycopy++) {
- NANDBUS_READ_BUFFER(nandbus, &params, sizeof(struct onfi_params));
- sigcount = params.signature[0] == 'O';
- sigcount += params.signature[1] == 'N';
- sigcount += params.signature[2] == 'F';
- sigcount += params.signature[3] == 'I';
- if (sigcount < 2)
- continue;
- if (onfi_crc(&params, 254) != params.crc)
- continue;
- found = 1;
- }
- if (!found)
- return (ENXIO);
-
- chip_params->luns = params.luns;
- chip_params->blocks_per_lun = le32dec(&params.blocks_per_lun);
- chip_params->pages_per_block = le32dec(&params.pages_per_block);
- chip_params->bytes_per_page = le32dec(&params.bytes_per_page);
- chip_params->spare_bytes_per_page = le16dec(&params.spare_bytes_per_page);
- chip_params->t_bers = le16dec(&params.t_bers);
- chip_params->t_prog = le16dec(&params.t_prog);
- chip_params->t_r = le16dec(&params.t_r);
- chip_params->t_ccs = le16dec(&params.t_ccs);
- chip_params->features = le16dec(&params.features);
- chip_params->address_cycles = params.address_cycles;
-
- return (0);
-}
-
-static int
-send_read_page(device_t nand, uint8_t start_command, uint8_t end_command,
- uint32_t row, uint32_t column)
-{
- device_t nandbus = device_get_parent(nand);
-
- if (NANDBUS_SEND_COMMAND(nandbus, start_command))
- return (ENXIO);
-
- if (nand_send_address(nand, row, column, -1))
- return (ENXIO);
-
- if (NANDBUS_SEND_COMMAND(nandbus, end_command))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-static int
-generic_read_page(device_t nand, uint32_t page, void *buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p raw read page %x[%x] at %x", nand, page, len, offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row,
- offset))
- return (ENXIO);
-
- DELAY(chip->t_r);
-
- NANDBUS_READ_BUFFER(nandbus, buf, len);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_read++;
-
- return (0);
-}
-
-static int
-generic_read_oob(device_t nand, uint32_t page, void* buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p raw read oob %x[%x] at %x", nand, page, len, offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page)) {
- nand_debug(NDBG_GEN,"page boundary check failed: %08x\n", page);
- return (ENXIO);
- }
-
- page_to_row(&chip->chip_geom, page, &row);
-
- offset += chip->chip_geom.page_size;
-
- if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row,
- offset))
- return (ENXIO);
-
- DELAY(chip->t_r);
-
- NANDBUS_READ_BUFFER(nandbus, buf, len);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-static int
-send_start_program_page(device_t nand, uint32_t row, uint32_t column)
-{
- device_t nandbus = device_get_parent(nand);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_PROG))
- return (ENXIO);
-
- if (nand_send_address(nand, row, column, -1))
- return (ENXIO);
-
- return (0);
-}
-
-static int
-send_end_program_page(device_t nandbus, uint8_t end_command)
-{
-
- if (NANDBUS_SEND_COMMAND(nandbus, end_command))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-static int
-generic_program_page(device_t nand, uint32_t page, void *buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p raw prog page %x[%x] at %x", nand, page, len,
- offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (send_start_program_page(nand, row, offset))
- return (ENXIO);
-
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (send_end_program_page(nandbus, NAND_CMD_PROG_END))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_written++;
-
- return (0);
-}
-
-static int
-generic_program_page_intlv(device_t nand, uint32_t page, void *buf,
- uint32_t len, uint32_t offset)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p raw prog page %x[%x] at %x", nand, page, len, offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (send_start_program_page(nand, row, offset))
- return (ENXIO);
-
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (send_end_program_page(nandbus, NAND_CMD_PROG_INTLV))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_written++;
-
- return (0);
-}
-
-static int
-generic_program_oob(device_t nand, uint32_t page, void* buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p raw prog oob %x[%x] at %x", nand, page, len,
- offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
- offset += chip->chip_geom.page_size;
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (send_start_program_page(nand, row, offset))
- return (ENXIO);
-
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (send_end_program_page(nandbus, NAND_CMD_PROG_END))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-static int
-send_erase_block(device_t nand, uint32_t row, uint8_t second_command)
-{
- device_t nandbus = device_get_parent(nand);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_ERASE))
- return (ENXIO);
-
- if (nand_send_address(nand, row, -1, -1))
- return (ENXIO);
-
- if (NANDBUS_SEND_COMMAND(nandbus, second_command))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-static int
-generic_erase_block(device_t nand, uint32_t block)
-{
- struct block_stat *blk_stat;
- struct nand_chip *chip;
- device_t nandbus;
- int row;
-
- nand_debug(NDBG_GEN,"%p erase block %x", nand, block);
- nandbus = device_get_parent(nand);
- chip = device_get_softc(nand);
-
- if (block >= (chip->chip_geom.blks_per_lun * chip->chip_geom.luns))
- return (ENXIO);
-
- row = (block << chip->chip_geom.blk_shift) &
- chip->chip_geom.blk_mask;
-
- nand_debug(NDBG_GEN,"%p erase block row %x", nand, row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- send_erase_block(nand, row, NAND_CMD_ERASE_END);
-
- DELAY(chip->t_bers);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- blk_stat = &(chip->blk_stat[block]);
- blk_stat->block_erased++;
-
- return (0);
-}
-
-static int
-generic_erase_block_intlv(device_t nand, uint32_t block)
-{
- struct block_stat *blk_stat;
- struct nand_chip *chip;
- device_t nandbus;
- int row;
-
- nand_debug(NDBG_GEN,"%p erase block %x", nand, block);
- nandbus = device_get_parent(nand);
- chip = device_get_softc(nand);
-
- if (block >= (chip->chip_geom.blks_per_lun * chip->chip_geom.luns))
- return (ENXIO);
-
- row = (block << chip->chip_geom.blk_shift) &
- chip->chip_geom.blk_mask;
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- send_erase_block(nand, row, NAND_CMD_ERASE_INTLV);
-
- DELAY(chip->t_bers);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- blk_stat = &(chip->blk_stat[block]);
- blk_stat->block_erased++;
-
- return (0);
-
-}
-
-static int
-onfi_is_blk_bad(device_t device, uint32_t block_number, uint8_t *bad)
-{
- struct nand_chip *chip;
- int page_number, i, j, err;
- uint8_t *oob;
-
- chip = device_get_softc(device);
-
- oob = malloc(chip->chip_geom.oob_size, M_NAND, M_WAITOK);
-
- page_number = block_number * chip->chip_geom.pgs_per_blk;
- *bad = 0;
- /* Check OOB of first and last page */
- for (i = 0; i < 2; i++, page_number+= chip->chip_geom.pgs_per_blk - 1) {
- err = generic_read_oob(device, page_number, oob,
- chip->chip_geom.oob_size, 0);
- if (err) {
- device_printf(device, "%s: cannot allocate oob\n",
- __func__);
- free(oob, M_NAND);
- return (ENOMEM);
- }
-
- for (j = 0; j < chip->chip_geom.oob_size; j++) {
- if (!oob[j]) {
- *bad = 1;
- free(oob, M_NAND);
- return (0);
- }
- }
- }
-
- free(oob, M_NAND);
-
- return (0);
-}
-
-static int
-send_small_read_page(device_t nand, uint8_t start_command,
- uint32_t row, uint32_t column)
-{
- device_t nandbus = device_get_parent(nand);
-
- if (NANDBUS_SEND_COMMAND(nandbus, start_command))
- return (ENXIO);
-
- if (nand_send_address(nand, row, column, -1))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-
-static int
-small_read_page(device_t nand, uint32_t page, void *buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p small read page %x[%x] at %x", nand, page, len, offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (offset < 256) {
- if (send_small_read_page(nand, NAND_CMD_SMALLA, row, offset))
- return (ENXIO);
- } else {
- offset -= 256;
- if (send_small_read_page(nandbus, NAND_CMD_SMALLB, row, offset))
- return (ENXIO);
- }
-
- DELAY(chip->t_r);
-
- NANDBUS_READ_BUFFER(nandbus, buf, len);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_read++;
-
- return (0);
-}
-
-static int
-small_read_oob(device_t nand, uint32_t page, void *buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p small read oob %x[%x] at %x", nand, page, len, offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (send_small_read_page(nand, NAND_CMD_SMALLOOB, row, 0))
- return (ENXIO);
-
- DELAY(chip->t_r);
-
- NANDBUS_READ_BUFFER(nandbus, buf, len);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_read++;
-
- return (0);
-}
-
-static int
-small_program_page(device_t nand, uint32_t page, void* buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p small prog page %x[%x] at %x", nand, page, len, offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (offset < 256) {
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SMALLA))
- return (ENXIO);
- } else {
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SMALLB))
- return (ENXIO);
- }
-
- if (send_start_program_page(nand, row, offset))
- return (ENXIO);
-
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (send_end_program_page(nandbus, NAND_CMD_PROG_END))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-static int
-small_program_oob(device_t nand, uint32_t page, void* buf, uint32_t len,
- uint32_t offset)
-{
- struct nand_chip *chip;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"%p small prog oob %x[%x] at %x", nand, page, len, offset);
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SMALLOOB))
- return (ENXIO);
-
- if (send_start_program_page(nand, row, offset))
- return (ENXIO);
-
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (send_end_program_page(nandbus, NAND_CMD_PROG_END))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-int
-nand_send_address(device_t nand, int32_t row, int32_t col, int8_t id)
-{
- struct nandbus_ivar *ivar;
- device_t nandbus;
- uint8_t addr;
- int err = 0;
- int i;
-
- nandbus = device_get_parent(nand);
- ivar = device_get_ivars(nand);
-
- if (id != -1) {
- nand_debug(NDBG_GEN,"send_address: send id %02x", id);
- err = NANDBUS_SEND_ADDRESS(nandbus, id);
- }
-
- if (!err && col != -1) {
- for (i = 0; i < ivar->cols; i++, col >>= 8) {
- addr = (uint8_t)(col & 0xff);
- nand_debug(NDBG_GEN,"send_address: send address column "
- "%02x", addr);
- err = NANDBUS_SEND_ADDRESS(nandbus, addr);
- if (err)
- break;
- }
- }
-
- if (!err && row != -1) {
- for (i = 0; i < ivar->rows; i++, row >>= 8) {
- addr = (uint8_t)(row & 0xff);
- nand_debug(NDBG_GEN,"send_address: send address row "
- "%02x", addr);
- err = NANDBUS_SEND_ADDRESS(nandbus, addr);
- if (err)
- break;
- }
- }
-
- return (err);
-}
-
-static int
-generic_is_blk_bad(device_t dev, uint32_t block, uint8_t *bad)
-{
- struct nand_chip *chip;
- int page_number, err, i;
- uint8_t *oob;
-
- chip = device_get_softc(dev);
-
- oob = malloc(chip->chip_geom.oob_size, M_NAND, M_WAITOK);
-
- page_number = block * chip->chip_geom.pgs_per_blk;
- *bad = 0;
-
- /* Check OOB of first and second page */
- for (i = 0; i < 2; i++) {
- err = NAND_READ_OOB(dev, page_number + i, oob,
- chip->chip_geom.oob_size, 0);
- if (err) {
- device_printf(dev, "%s: cannot allocate OOB\n",
- __func__);
- free(oob, M_NAND);
- return (ENOMEM);
- }
-
- if (!oob[0]) {
- *bad = 1;
- free(oob, M_NAND);
- return (0);
- }
- }
-
- free(oob, M_NAND);
-
- return (0);
-}
-
-static int
-generic_get_ecc(device_t dev, void *buf, void *ecc, int *needwrite)
-{
- struct nand_chip *chip = device_get_softc(dev);
- struct chip_geom *cg = &chip->chip_geom;
-
- return (NANDBUS_GET_ECC(device_get_parent(dev), buf, cg->page_size,
- ecc, needwrite));
-}
-
-static int
-generic_correct_ecc(device_t dev, void *buf, void *readecc, void *calcecc)
-{
- struct nand_chip *chip = device_get_softc(dev);
- struct chip_geom *cg = &chip->chip_geom;
-
- return (NANDBUS_CORRECT_ECC(device_get_parent(dev), buf,
- cg->page_size, readecc, calcecc));
-}
-
-
-#if 0
-int
-nand_chng_read_col(device_t nand, uint32_t col, void *buf, size_t len)
-{
- struct nand_chip *chip;
- device_t nandbus;
-
- chip = device_get_softc(nand);
- nandbus = device_get_parent(nand);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_READ_COL))
- return (ENXIO);
-
- if (NANDBUS_SEND_ADDRESS(nandbus, -1, col, -1))
- return (ENXIO);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_READ_COL_END))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- if (buf != NULL && len > 0)
- NANDBUS_READ_BUFFER(nandbus, buf, len);
-
- return (0);
-}
-
-int
-nand_chng_write_col(device_t dev, uint32_t col, void *buf,
- size_t len)
-{
- struct nand_chip *chip;
- device_t nandbus;
-
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_WRITE_COL))
- return (ENXIO);
-
- if (NANDBUS_SEND_ADDRESS(nandbus, -1, col, -1))
- return (ENXIO);
-
- if (buf != NULL && len > 0)
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_READ_COL_END))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- return (0);
-}
-
-int
-nand_copyback_read(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN," raw read page %x[%x] at %x", page, col, len);
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_CPBK, row, 0))
- return (ENXIO);
-
- DELAY(chip->t_r);
- if (check_fail(nandbus))
- return (ENXIO);
-
- if (buf != NULL && len > 0)
- NANDBUS_READ_BUFFER(nandbus, buf, len);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_read++;
-
- return (0);
-}
-
-int
-nand_copyback_prog(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"copyback prog page %x[%x]", page, len);
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_WRITE_COL))
- return (ENXIO);
-
- if (NANDBUS_SEND_ADDRESS(nandbus, row, col, -1))
- return (ENXIO);
-
- if (buf != NULL && len > 0)
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (send_end_program_page(nandbus, NAND_CMD_PROG_END))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_written++;
-
- return (0);
-}
-
-int
-nand_copyback_prog_intlv(device_t dev, uint32_t page)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
-
- nand_debug(NDBG_GEN,"cache prog page %x", page);
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (send_start_program_page(nand, row, 0))
- return (ENXIO);
-
- if (send_end_program_page(nandbus, NAND_CMD_PROG_INTLV))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_written++;
-
- return (0);
-}
-
-int
-nand_prog_cache(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len, uint8_t end)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
- uint8_t command;
-
- nand_debug(NDBG_GEN,"cache prog page %x[%x]", page, len);
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (!can_write(nandbus))
- return (ENXIO);
-
- if (send_start_program_page(dev, row, 0))
- return (ENXIO);
-
- NANDBUS_WRITE_BUFFER(nandbus, buf, len);
-
- if (end)
- command = NAND_CMD_PROG_END;
- else
- command = NAND_CMD_PROG_CACHE;
-
- if (send_end_program_page(nandbus, command))
- return (ENXIO);
-
- DELAY(chip->t_prog);
-
- if (check_fail(nandbus))
- return (ENXIO);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_written++;
-
- return (0);
-}
-
-int
-nand_read_cache(device_t dev, uint32_t page, uint32_t col,
- void *buf, size_t len, uint8_t end)
-{
- struct nand_chip *chip;
- struct page_stat *pg_stat;
- device_t nandbus;
- uint32_t row;
- uint8_t command;
-
- nand_debug(NDBG_GEN,"cache read page %x[%x] ", page, len);
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (nand_check_page_boundary(chip, page))
- return (ENXIO);
-
- page_to_row(&chip->chip_geom, page, &row);
-
- if (page != -1) {
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_READ))
- return (ENXIO);
-
- if (NANDBUS_SEND_ADDRESS(nandbus, row, col, -1))
- return (ENXIO);
- }
-
- if (end)
- command = NAND_CMD_READ_CACHE_END;
- else
- command = NAND_CMD_READ_CACHE;
-
- if (NANDBUS_SEND_COMMAND(nandbus, command))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- DELAY(chip->t_r);
- if (check_fail(nandbus))
- return (ENXIO);
-
- if (buf != NULL && len > 0)
- NANDBUS_READ_BUFFER(nandbus, buf, len);
-
- pg_stat = &(chip->pg_stat[page]);
- pg_stat->page_raw_read++;
-
- return (0);
-}
-
-int
-nand_get_feature(device_t dev, uint8_t feat, void *buf)
-{
- struct nand_chip *chip;
- device_t nandbus;
-
- nand_debug(NDBG_GEN,"nand get feature");
-
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_GET_FEATURE))
- return (ENXIO);
-
- if (NANDBUS_SEND_ADDRESS(nandbus, -1, -1, feat))
- return (ENXIO);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- DELAY(chip->t_r);
- NANDBUS_READ_BUFFER(nandbus, buf, 4);
-
- return (0);
-}
-
-int
-nand_set_feature(device_t dev, uint8_t feat, void *buf)
-{
- struct nand_chip *chip;
- device_t nandbus;
-
- nand_debug(NDBG_GEN,"nand set feature");
-
- chip = device_get_softc(dev);
- nandbus = device_get_parent(dev);
-
- if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SET_FEATURE))
- return (ENXIO);
-
- if (NANDBUS_SEND_ADDRESS(nandbus, -1, -1, feat))
- return (ENXIO);
-
- NANDBUS_WRITE_BUFFER(nandbus, buf, 4);
-
- if (NANDBUS_START_COMMAND(nandbus))
- return (ENXIO);
-
- return (0);
-}
-#endif
diff --git a/sys/dev/nand/nand_geom.c b/sys/dev/nand/nand_geom.c
deleted file mode 100644
index b814ffc4e0a9..000000000000
--- a/sys/dev/nand/nand_geom.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-#include <sys/uio.h>
-#include <sys/bio.h>
-#include <geom/geom.h>
-#include <geom/geom_disk.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-#include <dev/nand/nand_dev.h>
-#include "nand_if.h"
-#include "nandbus_if.h"
-
-#define BIO_NAND_STD ((void *)1)
-#define BIO_NAND_RAW ((void *)2)
-
-static disk_ioctl_t nand_ioctl;
-static disk_getattr_t nand_getattr;
-static disk_strategy_t nand_strategy;
-static disk_strategy_t nand_strategy_raw;
-
-static int
-nand_read(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len)
-{
-
- nand_debug(NDBG_GEOM, "Read from chip %d [%p] at %d", chip->num, chip,
- offset);
-
- return (nand_read_pages(chip, offset, buf, len));
-}
-
-static int
-nand_write(struct nand_chip *chip, uint32_t offset, void* buf, uint32_t len)
-{
-
- nand_debug(NDBG_GEOM, "Write to chip %d [%p] at %d", chip->num, chip,
- offset);
-
- return (nand_prog_pages(chip, offset, buf, len));
-}
-
-static int
-nand_read_raw(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len)
-{
- nand_debug(NDBG_GEOM, "Raw read from chip %d [%p] at %d", chip->num,
- chip, offset);
-
- return (nand_read_pages_raw(chip, offset, buf, len));
-}
-
-static int
-nand_write_raw(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len)
-{
-
- nand_debug(NDBG_GEOM, "Raw write to chip %d [%p] at %d", chip->num,
- chip, offset);
-
- return (nand_prog_pages_raw(chip, offset, buf, len));
-}
-
-static void
-nand_strategy(struct bio *bp)
-{
- struct nand_chip *chip;
-
- chip = (struct nand_chip *)bp->bio_disk->d_drv1;
-
- bp->bio_driver1 = BIO_NAND_STD;
-
- nand_debug(NDBG_GEOM, "Strategy %s on chip %d [%p]",
- bp->bio_cmd == BIO_READ ? "READ" :
- (bp->bio_cmd == BIO_WRITE ? "WRITE" :
- (bp->bio_cmd == BIO_DELETE ? "DELETE" : "UNKNOWN")),
- chip->num, chip);
-
- mtx_lock(&chip->qlock);
- bioq_insert_tail(&chip->bioq, bp);
- mtx_unlock(&chip->qlock);
- taskqueue_enqueue(chip->tq, &chip->iotask);
-}
-
-static void
-nand_strategy_raw(struct bio *bp)
-{
- struct nand_chip *chip;
-
- chip = (struct nand_chip *)bp->bio_disk->d_drv1;
-
- /* Inform taskqueue that it's a raw access */
- bp->bio_driver1 = BIO_NAND_RAW;
-
- nand_debug(NDBG_GEOM, "Strategy %s on chip %d [%p]",
- bp->bio_cmd == BIO_READ ? "READ" :
- (bp->bio_cmd == BIO_WRITE ? "WRITE" :
- (bp->bio_cmd == BIO_DELETE ? "DELETE" : "UNKNOWN")),
- chip->num, chip);
-
- mtx_lock(&chip->qlock);
- bioq_insert_tail(&chip->bioq, bp);
- mtx_unlock(&chip->qlock);
- taskqueue_enqueue(chip->tq, &chip->iotask);
-}
-
-static int
-nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset,
- uint32_t len, uint8_t *data, uint8_t write)
-{
- struct chip_geom *cg;
- int ret = 0;
-
- cg = &chip->chip_geom;
-
- if (!write)
- ret = nand_read_oob(chip, page, data, cg->oob_size);
- else
- ret = nand_prog_oob(chip, page, data, cg->oob_size);
-
- return (ret);
-}
-
-static int
-nand_getattr(struct bio *bp)
-{
- struct nand_chip *chip;
- struct chip_geom *cg;
- device_t dev;
- int val;
-
- if (bp->bio_disk == NULL || bp->bio_disk->d_drv1 == NULL)
- return (ENXIO);
-
- chip = (struct nand_chip *)bp->bio_disk->d_drv1;
- cg = &(chip->chip_geom);
-
- dev = device_get_parent(chip->dev);
- dev = device_get_parent(dev);
-
- if (strcmp(bp->bio_attribute, "NAND::device") == 0) {
- if (bp->bio_length != sizeof(dev))
- return (EFAULT);
- bcopy(&dev, bp->bio_data, sizeof(dev));
- } else {
- if (strcmp(bp->bio_attribute, "NAND::oobsize") == 0)
- val = cg->oob_size;
- else if (strcmp(bp->bio_attribute, "NAND::pagesize") == 0)
- val = cg->page_size;
- else if (strcmp(bp->bio_attribute, "NAND::blocksize") == 0)
- val = cg->block_size;
- else
- return (-1);
- if (bp->bio_length != sizeof(val))
- return (EFAULT);
- bcopy(&val, bp->bio_data, sizeof(val));
- }
- bp->bio_completed = bp->bio_length;
- return (0);
-}
-
-static int
-nand_ioctl(struct disk *ndisk, u_long cmd, void *data, int fflag,
- struct thread *td)
-{
- struct nand_chip *chip;
- struct chip_geom *cg;
- struct nand_oob_rw *oob_rw = NULL;
- struct nand_raw_rw *raw_rw = NULL;
- device_t nandbus;
- size_t bufsize = 0, len = 0;
- size_t raw_size;
- off_t off;
- uint8_t *buf = NULL;
- int ret = 0;
- uint8_t status;
-
- chip = (struct nand_chip *)ndisk->d_drv1;
- cg = &chip->chip_geom;
- nandbus = device_get_parent(chip->dev);
-
- if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) {
- raw_rw = (struct nand_raw_rw *)data;
- raw_size = cg->pgs_per_blk * (cg->page_size + cg->oob_size);
-
- /* Check if len is not bigger than chip size */
- if (raw_rw->len > raw_size)
- return (EFBIG);
-
- /*
- * Do not ask for too much memory, in case of large transfers
- * read/write in 16-pages chunks
- */
- bufsize = 16 * (cg->page_size + cg->oob_size);
- if (raw_rw->len < bufsize)
- bufsize = raw_rw->len;
-
- buf = malloc(bufsize, M_NAND, M_WAITOK);
- len = raw_rw->len;
- off = 0;
- }
-
- switch (cmd) {
- case NAND_IO_ERASE:
- ret = nand_erase_blocks(chip, ((off_t *)data)[0],
- ((off_t *)data)[1]);
- break;
-
- case NAND_IO_OOB_READ:
- oob_rw = (struct nand_oob_rw *)data;
- ret = nand_oob_access(chip, oob_rw->page, 0,
- oob_rw->len, oob_rw->data, 0);
- break;
-
- case NAND_IO_OOB_PROG:
- oob_rw = (struct nand_oob_rw *)data;
- ret = nand_oob_access(chip, oob_rw->page, 0,
- oob_rw->len, oob_rw->data, 1);
- break;
-
- case NAND_IO_GET_STATUS:
- NANDBUS_LOCK(nandbus);
- ret = NANDBUS_GET_STATUS(nandbus, &status);
- if (ret == 0)
- *(uint8_t *)data = status;
- NANDBUS_UNLOCK(nandbus);
- break;
-
- case NAND_IO_RAW_PROG:
- while (len > 0) {
- if (len < bufsize)
- bufsize = len;
-
- ret = copyin(raw_rw->data + off, buf, bufsize);
- if (ret)
- break;
- ret = nand_prog_pages_raw(chip, raw_rw->off + off, buf,
- bufsize);
- if (ret)
- break;
- len -= bufsize;
- off += bufsize;
- }
- break;
-
- case NAND_IO_RAW_READ:
- while (len > 0) {
- if (len < bufsize)
- bufsize = len;
-
- ret = nand_read_pages_raw(chip, raw_rw->off + off, buf,
- bufsize);
- if (ret)
- break;
-
- ret = copyout(buf, raw_rw->data + off, bufsize);
- if (ret)
- break;
- len -= bufsize;
- off += bufsize;
- }
- break;
-
- case NAND_IO_GET_CHIP_PARAM:
- nand_get_chip_param(chip, (struct chip_param_io *)data);
- break;
-
- default:
- printf("Unknown nand_ioctl request \n");
- ret = EIO;
- }
-
- if (buf)
- free(buf, M_NAND);
-
- return (ret);
-}
-
-static void
-nand_io_proc(void *arg, int pending)
-{
- struct nand_chip *chip = arg;
- struct bio *bp;
- int err = 0;
-
- for (;;) {
- mtx_lock(&chip->qlock);
- bp = bioq_takefirst(&chip->bioq);
- mtx_unlock(&chip->qlock);
- if (bp == NULL)
- break;
-
- if (bp->bio_driver1 == BIO_NAND_STD) {
- if (bp->bio_cmd == BIO_READ) {
- err = nand_read(chip,
- bp->bio_offset & 0xffffffff,
- bp->bio_data, bp->bio_bcount);
- } else if (bp->bio_cmd == BIO_WRITE) {
- err = nand_write(chip,
- bp->bio_offset & 0xffffffff,
- bp->bio_data, bp->bio_bcount);
- }
- } else if (bp->bio_driver1 == BIO_NAND_RAW) {
- if (bp->bio_cmd == BIO_READ) {
- err = nand_read_raw(chip,
- bp->bio_offset & 0xffffffff,
- bp->bio_data, bp->bio_bcount);
- } else if (bp->bio_cmd == BIO_WRITE) {
- err = nand_write_raw(chip,
- bp->bio_offset & 0xffffffff,
- bp->bio_data, bp->bio_bcount);
- }
- } else
- panic("Unknown access type in bio->bio_driver1\n");
-
- if (bp->bio_cmd == BIO_DELETE) {
- nand_debug(NDBG_GEOM, "Delete on chip%d offset %lld "
- "length %ld\n", chip->num, bp->bio_offset,
- bp->bio_bcount);
- err = nand_erase_blocks(chip,
- bp->bio_offset & 0xffffffff,
- bp->bio_bcount);
- }
-
- if (err == 0 || err == ECC_CORRECTABLE)
- bp->bio_resid = 0;
- else {
- nand_debug(NDBG_GEOM,"nand_[read|write|erase_blocks] "
- "error: %d\n", err);
-
- bp->bio_error = EIO;
- bp->bio_flags |= BIO_ERROR;
- bp->bio_resid = bp->bio_bcount;
- }
- biodone(bp);
- }
-}
-
-int
-create_geom_disk(struct nand_chip *chip)
-{
- struct disk *ndisk, *rdisk;
-
- /* Create the disk device */
- ndisk = disk_alloc();
- ndisk->d_strategy = nand_strategy;
- ndisk->d_ioctl = nand_ioctl;
- ndisk->d_getattr = nand_getattr;
- ndisk->d_name = "gnand";
- ndisk->d_drv1 = chip;
- ndisk->d_maxsize = chip->chip_geom.block_size;
- ndisk->d_sectorsize = chip->chip_geom.page_size;
- ndisk->d_mediasize = chip->chip_geom.chip_size;
- ndisk->d_unit = chip->num +
- 10 * device_get_unit(device_get_parent(chip->dev));
-
- /*
- * When using BBT, make two last blocks of device unavailable
- * to user (because those are used to store BBT table).
- */
- if (chip->bbt != NULL)
- ndisk->d_mediasize -= (2 * chip->chip_geom.block_size);
-
- ndisk->d_flags = DISKFLAG_CANDELETE;
-
- snprintf(ndisk->d_ident, sizeof(ndisk->d_ident),
- "nand: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id);
- ndisk->d_rotation_rate = DISK_RR_NON_ROTATING;
-
- disk_create(ndisk, DISK_VERSION);
-
- /* Create the RAW disk device */
- rdisk = disk_alloc();
- rdisk->d_strategy = nand_strategy_raw;
- rdisk->d_ioctl = nand_ioctl;
- rdisk->d_getattr = nand_getattr;
- rdisk->d_name = "gnand.raw";
- rdisk->d_drv1 = chip;
- rdisk->d_maxsize = chip->chip_geom.block_size;
- rdisk->d_sectorsize = chip->chip_geom.page_size;
- rdisk->d_mediasize = chip->chip_geom.chip_size;
- rdisk->d_unit = chip->num +
- 10 * device_get_unit(device_get_parent(chip->dev));
-
- rdisk->d_flags = DISKFLAG_CANDELETE;
-
- snprintf(rdisk->d_ident, sizeof(rdisk->d_ident),
- "nand_raw: Man:0x%02x Dev:0x%02x", chip->id.man_id,
- chip->id.dev_id);
- rdisk->d_rotation_rate = DISK_RR_NON_ROTATING;
-
- disk_create(rdisk, DISK_VERSION);
-
- chip->ndisk = ndisk;
- chip->rdisk = rdisk;
-
- mtx_init(&chip->qlock, "NAND I/O lock", NULL, MTX_DEF);
- bioq_init(&chip->bioq);
-
- TASK_INIT(&chip->iotask, 0, nand_io_proc, chip);
- chip->tq = taskqueue_create("nand_taskq", M_WAITOK,
- taskqueue_thread_enqueue, &chip->tq);
- taskqueue_start_threads(&chip->tq, 1, PI_DISK, "nand taskq");
-
- if (bootverbose)
- device_printf(chip->dev, "Created gnand%d for chip [0x%0x, "
- "0x%0x]\n", ndisk->d_unit, chip->id.man_id,
- chip->id.dev_id);
-
- return (0);
-}
-
-void
-destroy_geom_disk(struct nand_chip *chip)
-{
- struct bio *bp;
-
- taskqueue_free(chip->tq);
- disk_destroy(chip->ndisk);
- disk_destroy(chip->rdisk);
-
- mtx_lock(&chip->qlock);
- for (;;) {
- bp = bioq_takefirst(&chip->bioq);
- if (bp == NULL)
- break;
- bp->bio_error = EIO;
- bp->bio_flags |= BIO_ERROR;
- bp->bio_resid = bp->bio_bcount;
-
- biodone(bp);
- }
- mtx_unlock(&chip->qlock);
-
- mtx_destroy(&chip->qlock);
-}
diff --git a/sys/dev/nand/nand_id.c b/sys/dev/nand/nand_id.c
deleted file mode 100644
index 7259c951bfc9..000000000000
--- a/sys/dev/nand/nand_id.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <dev/nand/nand.h>
-
-struct nand_params nand_ids[] = {
- { { NAND_MAN_SAMSUNG, 0x75 }, "Samsung K9F5608U0B NAND 32MiB 8-bit",
- 0x20, 0x200, 0x10, 0x20, 0 },
- { { NAND_MAN_SAMSUNG, 0xf1 }, "Samsung K9F1G08U0A NAND 128MiB 3,3V 8-bit",
- 0x80, 0x800, 0x40, 0x40, 0 },
- { { NAND_MAN_SAMSUNG, 0xda }, "Samsung K9F2G08U0A NAND 256MiB 3,3V 8-bit",
- 0x100, 0x800, 0x40, 0x40, 0 },
- { { NAND_MAN_SAMSUNG, 0xdc }, "Samsung NAND 512MiB 3,3V 8-bit",
- 0x200, 0x800, 0x40, 0x40, 0 },
- { { NAND_MAN_SAMSUNG, 0xd3 }, "Samsung NAND 1GiB 3,3V 8-bit",
- 0x400, 0x800, 0x40, 0x40, 0 },
- { { NAND_MAN_HYNIX, 0x76 }, "Hynix NAND 64MiB 3,3V 8-bit",
- 0x40, 0x200, 0x10, 0x20, 0 },
- { { NAND_MAN_HYNIX, 0xdc }, "Hynix NAND 512MiB 3,3V 8-bit",
- 0x200, 0x800, 0x40, 0x40, 0 },
- { { NAND_MAN_HYNIX, 0x79 }, "Hynix NAND 128MB 3,3V 8-bit",
- 0x80, 0x200, 0x10, 0x20, 0 },
- { { NAND_MAN_STMICRO, 0xf1 }, "STMicro 128MB 3,3V 8-bit",
- 0x80, 2048, 64, 0x40, 0 },
- { { NAND_MAN_MICRON, 0xcc }, "Micron NAND 512MiB 3,3V 16-bit",
- 0x200, 2048, 64, 0x40, 0 },
-};
-
-struct nand_params *nand_get_params(struct nand_id *id)
-{
- int i;
-
- for (i = 0; i < nitems(nand_ids); i++)
- if (nand_ids[i].id.man_id == id->man_id &&
- nand_ids[i].id.dev_id == id->dev_id)
- return (&nand_ids[i]);
-
- return (NULL);
-}
diff --git a/sys/dev/nand/nand_if.m b/sys/dev/nand/nand_if.m
deleted file mode 100644
index 49c8879b6890..000000000000
--- a/sys/dev/nand/nand_if.m
+++ /dev/null
@@ -1,168 +0,0 @@
-#-
-# Copyright (C) 2009-2012 Semihalf
-# All rights reserved.
-#
-# 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
-#
-# $FreeBSD$
-
-# NAND chip interface description
-#
-
-#include <sys/bus.h>
-#include <dev/nand/nand.h>
-
-INTERFACE nand;
-
-CODE {
- static int nand_method_not_supported(device_t dev)
- {
- return (ENOENT);
- }
-};
-
-# Read NAND page
-#
-# Return values:
-# 0: Success
-#
-METHOD int read_page {
- device_t dev;
- uint32_t page;
- void* buf;
- uint32_t len;
- uint32_t offset;
-};
-
-# Program NAND page
-#
-# Return values:
-# 0: Success
-#
-METHOD int program_page {
- device_t dev;
- uint32_t page;
- void* buf;
- uint32_t len;
- uint32_t offset;
-};
-
-# Program NAND page interleaved
-#
-# Return values:
-# 0: Success
-#
-METHOD int program_page_intlv {
- device_t dev;
- uint32_t page;
- void* buf;
- uint32_t len;
- uint32_t offset;
-} DEFAULT nand_method_not_supported;
-
-# Read NAND oob
-#
-# Return values:
-# 0: Success
-#
-METHOD int read_oob {
- device_t dev;
- uint32_t page;
- void* buf;
- uint32_t len;
- uint32_t offset;
-};
-
-# Program NAND oob
-#
-# Return values:
-# 0: Success
-#
-METHOD int program_oob {
- device_t dev;
- uint32_t page;
- void* buf;
- uint32_t len;
- uint32_t offset;
-};
-
-# Erase NAND block
-#
-# Return values:
-# 0: Success
-#
-METHOD int erase_block {
- device_t dev;
- uint32_t block;
-};
-
-# Erase NAND block interleaved
-#
-# Return values:
-# 0: Success
-#
-METHOD int erase_block_intlv {
- device_t dev;
- uint32_t block;
-} DEFAULT nand_method_not_supported;
-
-# NAND get status
-#
-# Return values:
-# 0: Success
-#
-METHOD int get_status {
- device_t dev;
- uint8_t *status;
-};
-
-# NAND check if block is bad
-#
-# Return values:
-# 0: Success
-#
-METHOD int is_blk_bad {
- device_t dev;
- uint32_t block_number;
- uint8_t *bad;
-};
-
-# NAND get ECC
-#
-#
-METHOD int get_ecc {
- device_t dev;
- void *buf;
- void *ecc;
- int *needwrite;
-};
-
-# NAND correct ECC
-#
-#
-METHOD int correct_ecc {
- device_t dev;
- void *buf;
- void *readecc;
- void *calcecc;
-};
-
diff --git a/sys/dev/nand/nandbus.c b/sys/dev/nand/nandbus.c
deleted file mode 100644
index 003c1797af64..000000000000
--- a/sys/dev/nand/nandbus.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/proc.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/condvar.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-#include "nand_if.h"
-#include "nandbus_if.h"
-#include "nfc_if.h"
-
-#define NAND_NCS 4
-
-static int nandbus_probe(device_t dev);
-static int nandbus_attach(device_t dev);
-static int nandbus_detach(device_t dev);
-
-static int nandbus_child_location_str(device_t, device_t, char *, size_t);
-static int nandbus_child_pnpinfo_str(device_t, device_t, char *, size_t);
-
-static int nandbus_get_status(device_t, uint8_t *);
-static void nandbus_read_buffer(device_t, void *, uint32_t);
-static int nandbus_select_cs(device_t, uint8_t);
-static int nandbus_send_command(device_t, uint8_t);
-static int nandbus_send_address(device_t, uint8_t);
-static int nandbus_start_command(device_t);
-static int nandbus_wait_ready(device_t, uint8_t *);
-static void nandbus_write_buffer(device_t, void *, uint32_t);
-static int nandbus_get_ecc(device_t, void *, uint32_t, void *, int *);
-static int nandbus_correct_ecc(device_t, void *, int, void *, void *);
-static void nandbus_lock(device_t);
-static void nandbus_unlock(device_t);
-
-static int nand_readid(device_t, uint8_t *, uint8_t *);
-static int nand_probe_onfi(device_t, uint8_t *);
-static int nand_reset(device_t);
-
-struct nandbus_softc {
- device_t dev;
- struct cv nandbus_cv;
- struct mtx nandbus_mtx;
- uint8_t busy;
-};
-
-static device_method_t nandbus_methods[] = {
- /* device interface */
- DEVMETHOD(device_probe, nandbus_probe),
- DEVMETHOD(device_attach, nandbus_attach),
- DEVMETHOD(device_detach, nandbus_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
- DEVMETHOD(bus_child_pnpinfo_str, nandbus_child_pnpinfo_str),
- DEVMETHOD(bus_child_location_str, nandbus_child_location_str),
-
- /* nandbus interface */
- DEVMETHOD(nandbus_get_status, nandbus_get_status),
- DEVMETHOD(nandbus_read_buffer, nandbus_read_buffer),
- DEVMETHOD(nandbus_select_cs, nandbus_select_cs),
- DEVMETHOD(nandbus_send_command, nandbus_send_command),
- DEVMETHOD(nandbus_send_address, nandbus_send_address),
- DEVMETHOD(nandbus_start_command,nandbus_start_command),
- DEVMETHOD(nandbus_wait_ready, nandbus_wait_ready),
- DEVMETHOD(nandbus_write_buffer, nandbus_write_buffer),
- DEVMETHOD(nandbus_get_ecc, nandbus_get_ecc),
- DEVMETHOD(nandbus_correct_ecc, nandbus_correct_ecc),
- DEVMETHOD(nandbus_lock, nandbus_lock),
- DEVMETHOD(nandbus_unlock, nandbus_unlock),
- { 0, 0 }
-};
-
-devclass_t nandbus_devclass;
-
-driver_t nandbus_driver = {
- "nandbus",
- nandbus_methods,
- sizeof(struct nandbus_softc)
-};
-
-DRIVER_MODULE(nandbus, nand, nandbus_driver, nandbus_devclass, 0, 0);
-
-int
-nandbus_create(device_t nfc)
-{
- device_t child;
-
- child = device_add_child(nfc, "nandbus", -1);
- if (!child)
- return (ENODEV);
-
- bus_generic_attach(nfc);
-
- return(0);
-}
-
-void
-nandbus_destroy(device_t nfc)
-{
- device_t *children;
- int nchildren, i;
-
- mtx_lock(&Giant);
- /* Detach & delete all children */
- if (!device_get_children(nfc, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- device_delete_child(nfc, children[i]);
-
- free(children, M_TEMP);
- }
- mtx_unlock(&Giant);
-}
-
-static int
-nandbus_probe(device_t dev)
-{
-
- device_set_desc(dev, "NAND bus");
-
- return (0);
-}
-
-static int
-nandbus_attach(device_t dev)
-{
- device_t child, nfc;
- struct nand_id chip_id;
- struct nandbus_softc *sc;
- struct nandbus_ivar *ivar;
- struct nand_softc *nfc_sc;
- struct nand_params *chip_params;
- uint8_t cs, onfi;
-
- sc = device_get_softc(dev);
- sc->dev = dev;
-
- nfc = device_get_parent(dev);
- nfc_sc = device_get_softc(nfc);
-
- mtx_init(&sc->nandbus_mtx, "nandbus lock", NULL, MTX_DEF);
- cv_init(&sc->nandbus_cv, "nandbus cv");
-
- /* Check each possible CS for existing nand devices */
- for (cs = 0; cs < NAND_NCS; cs++) {
- nand_debug(NDBG_BUS,"probe chip select %x", cs);
-
- /* Select & reset chip */
- if (nandbus_select_cs(dev, cs))
- break;
-
- if (nand_reset(dev))
- continue;
-
- /* Read manufacturer and device id */
- if (nand_readid(dev, &chip_id.man_id, &chip_id.dev_id))
- continue;
-
- if (chip_id.man_id == 0xff)
- continue;
-
- /*
- * First try to get info from the table. If that fails, see if
- * the chip can provide ONFI info. We check the table first to
- * allow table entries to override info from chips that are
- * known to provide bad ONFI data.
- */
- onfi = 0;
- chip_params = nand_get_params(&chip_id);
- if (chip_params == NULL) {
- nand_probe_onfi(dev, &onfi);
- }
-
- /*
- * At this point it appears there is a chip at this chipselect,
- * so if we can't work with it, whine about it.
- */
- if (chip_params == NULL && onfi == 0) {
- if (bootverbose || (nand_debug_flag & NDBG_BUS))
- printf("Chip params not found, chipsel: %d "
- "(manuf: 0x%0x, chipid: 0x%0x, onfi: %d)\n",
- cs, chip_id.man_id, chip_id.dev_id, onfi);
- continue;
- }
-
- ivar = malloc(sizeof(struct nandbus_ivar),
- M_NAND, M_WAITOK);
-
- if (onfi == 1) {
- ivar->cs = cs;
- ivar->cols = 0;
- ivar->rows = 0;
- ivar->params = NULL;
- ivar->man_id = chip_id.man_id;
- ivar->dev_id = chip_id.dev_id;
- ivar->is_onfi = onfi;
- ivar->chip_cdev_name = nfc_sc->chip_cdev_name;
-
- child = device_add_child(dev, NULL, -1);
- device_set_ivars(child, ivar);
- continue;
- }
-
- ivar->cs = cs;
- ivar->cols = 1;
- ivar->rows = 2;
- ivar->params = chip_params;
- ivar->man_id = chip_id.man_id;
- ivar->dev_id = chip_id.dev_id;
- ivar->is_onfi = onfi;
- ivar->chip_cdev_name = nfc_sc->chip_cdev_name;
-
- /*
- * Check what type of device we have.
- * devices bigger than 32MiB have on more row (3)
- */
- if (chip_params->chip_size > 32)
- ivar->rows++;
- /* Large page devices have one more col (2) */
- if (chip_params->chip_size >= 128 &&
- chip_params->page_size > 512)
- ivar->cols++;
-
- child = device_add_child(dev, NULL, -1);
- device_set_ivars(child, ivar);
- }
-
- bus_generic_attach(dev);
- return (0);
-}
-
-static int
-nandbus_detach(device_t dev)
-{
- struct nandbus_softc *sc;
-
- sc = device_get_softc(dev);
-
- bus_generic_detach(dev);
-
- mtx_destroy(&sc->nandbus_mtx);
- cv_destroy(&sc->nandbus_cv);
-
- return (0);
-}
-
-static int
-nandbus_child_location_str(device_t bus, device_t child, char *buf,
- size_t buflen)
-{
- struct nandbus_ivar *ivar = device_get_ivars(child);
-
- snprintf(buf, buflen, "at cs#%d", ivar->cs);
- return (0);
-}
-
-static int
-nandbus_child_pnpinfo_str(device_t bus, device_t child, char *buf,
- size_t buflen)
-{
- // XXX man id, model id ????
- *buf = '\0';
- return (0);
-}
-
-static int
-nand_readid(device_t bus, uint8_t *man_id, uint8_t *dev_id)
-{
- device_t nfc;
-
- if (!bus || !man_id || !dev_id)
- return (EINVAL);
-
- nand_debug(NDBG_BUS,"read id");
-
- nfc = device_get_parent(bus);
-
- if (NFC_SEND_COMMAND(nfc, NAND_CMD_READ_ID)) {
- nand_debug(NDBG_BUS,"Error : could not send READ ID command");
- return (ENXIO);
- }
-
- if (NFC_SEND_ADDRESS(nfc, 0)) {
- nand_debug(NDBG_BUS,"Error : could not sent address to chip");
- return (ENXIO);
- }
-
- if (NFC_START_COMMAND(nfc) != 0) {
- nand_debug(NDBG_BUS,"Error : could not start command");
- return (ENXIO);
- }
-
- DELAY(25);
-
- *man_id = NFC_READ_BYTE(nfc);
- *dev_id = NFC_READ_BYTE(nfc);
-
- nand_debug(NDBG_BUS,"manufacturer id: %x chip id: %x", *man_id,
- *dev_id);
-
- return (0);
-}
-
-static int
-nand_probe_onfi(device_t bus, uint8_t *onfi_compliant)
-{
- device_t nfc;
- char onfi_id[] = {'O', 'N', 'F', 'I', '\0'};
- int i;
-
- nand_debug(NDBG_BUS,"probing ONFI");
-
- nfc = device_get_parent(bus);
-
- if (NFC_SEND_COMMAND(nfc, NAND_CMD_READ_ID)) {
- nand_debug(NDBG_BUS,"Error : could not sent READ ID command");
- return (ENXIO);
- }
-
- if (NFC_SEND_ADDRESS(nfc, ONFI_SIG_ADDR)) {
- nand_debug(NDBG_BUS,"Error : could not sent address to chip");
- return (ENXIO);
- }
-
- if (NFC_START_COMMAND(nfc) != 0) {
- nand_debug(NDBG_BUS,"Error : could not start command");
- return (ENXIO);
- }
- for (i = 0; onfi_id[i] != '\0'; i++)
- if (NFC_READ_BYTE(nfc) != onfi_id[i]) {
- nand_debug(NDBG_BUS,"ONFI non-compliant");
- *onfi_compliant = 0;
- return (0);
- }
-
- nand_debug(NDBG_BUS,"ONFI compliant");
- *onfi_compliant = 1;
-
- return (0);
-}
-
-static int
-nand_reset(device_t bus)
-{
- device_t nfc;
- nand_debug(NDBG_BUS,"resetting...");
-
- nfc = device_get_parent(bus);
-
- if (NFC_SEND_COMMAND(nfc, NAND_CMD_RESET) != 0) {
- nand_debug(NDBG_BUS,"Error : could not sent RESET command");
- return (ENXIO);
- }
-
- if (NFC_START_COMMAND(nfc) != 0) {
- nand_debug(NDBG_BUS,"Error : could not start RESET command");
- return (ENXIO);
- }
-
- DELAY(1000);
-
- return (0);
-}
-
-void
-nandbus_lock(device_t dev)
-{
- struct nandbus_softc *sc;
-
- sc = device_get_softc(dev);
-
- mtx_lock(&sc->nandbus_mtx);
- if (sc->busy)
- cv_wait(&sc->nandbus_cv, &sc->nandbus_mtx);
- sc->busy = 1;
- mtx_unlock(&sc->nandbus_mtx);
-}
-
-void
-nandbus_unlock(device_t dev)
-{
- struct nandbus_softc *sc;
-
- sc = device_get_softc(dev);
-
- mtx_lock(&sc->nandbus_mtx);
- sc->busy = 0;
- cv_signal(&sc->nandbus_cv);
- mtx_unlock(&sc->nandbus_mtx);
-}
-
-int
-nandbus_select_cs(device_t dev, uint8_t cs)
-{
-
- return (NFC_SELECT_CS(device_get_parent(dev), cs));
-}
-
-int
-nandbus_send_command(device_t dev, uint8_t command)
-{
- int err;
-
- if ((err = NFC_SEND_COMMAND(device_get_parent(dev), command)))
- nand_debug(NDBG_BUS,"Err: Could not send command %x, err %x",
- command, err);
-
- return (err);
-}
-
-int
-nandbus_send_address(device_t dev, uint8_t address)
-{
- int err;
-
- if ((err = NFC_SEND_ADDRESS(device_get_parent(dev), address)))
- nand_debug(NDBG_BUS,"Err: Could not send address %x, err %x",
- address, err);
-
- return (err);
-}
-
-int
-nandbus_start_command(device_t dev)
-{
- int err;
-
- if ((err = NFC_START_COMMAND(device_get_parent(dev))))
- nand_debug(NDBG_BUS,"Err: Could not start command, err %x",
- err);
-
- return (err);
-}
-
-void
-nandbus_read_buffer(device_t dev, void *buf, uint32_t len)
-{
-
- NFC_READ_BUF(device_get_parent(dev), buf, len);
-}
-
-void
-nandbus_write_buffer(device_t dev, void *buf, uint32_t len)
-{
-
- NFC_WRITE_BUF(device_get_parent(dev), buf, len);
-}
-
-int
-nandbus_get_status(device_t dev, uint8_t *status)
-{
- int err;
-
- if ((err = NANDBUS_SEND_COMMAND(dev, NAND_CMD_STATUS)))
- return (err);
- if ((err = NANDBUS_START_COMMAND(dev)))
- return (err);
-
- *status = NFC_READ_BYTE(device_get_parent(dev));
-
- return (0);
-}
-
-int
-nandbus_wait_ready(device_t dev, uint8_t *status)
-{
- struct timeval tv, tv2;
-
- tv2.tv_sec = 0;
- tv2.tv_usec = 50 * 5000; /* 250ms */
-
- getmicrotime(&tv);
- timevaladd(&tv, &tv2);
-
- do {
- if (NANDBUS_GET_STATUS(dev, status))
- return (ENXIO);
-
- if (*status & NAND_STATUS_RDY)
- return (0);
-
- getmicrotime(&tv2);
- } while (timevalcmp(&tv2, &tv, <=));
-
- return (EBUSY);
-}
-
-int
-nandbus_get_ecc(device_t dev, void *buf, uint32_t pagesize, void *ecc,
- int *needwrite)
-{
-
- return (NFC_GET_ECC(device_get_parent(dev), buf, pagesize, ecc, needwrite));
-}
-
-int
-nandbus_correct_ecc(device_t dev, void *buf, int pagesize, void *readecc,
- void *calcecc)
-{
-
- return (NFC_CORRECT_ECC(device_get_parent(dev), buf, pagesize,
- readecc, calcecc));
-}
-
diff --git a/sys/dev/nand/nandbus.h b/sys/dev/nand/nandbus.h
deleted file mode 100644
index 6dd4cbf26daa..000000000000
--- a/sys/dev/nand/nandbus.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _NANDBUS_H_
-#define _NANDBUS_H_
-
-struct nandbus_ivar {
- uint8_t cs;
- uint8_t cols;
- uint8_t rows;
- uint8_t man_id;
- uint8_t dev_id;
- uint8_t is_onfi;
- char *chip_cdev_name;
- struct nand_params *params;
-};
-
-extern devclass_t nandbus_devclass;
-extern driver_t nandbus_driver;
-
-int nandbus_create(device_t nfc);
-void nandbus_destroy(device_t nfc);
-
-#endif /* _NANDBUS_H_ */
diff --git a/sys/dev/nand/nandbus_if.m b/sys/dev/nand/nandbus_if.m
deleted file mode 100644
index e914e18de661..000000000000
--- a/sys/dev/nand/nandbus_if.m
+++ /dev/null
@@ -1,100 +0,0 @@
-#-
-# Copyright (C) 2009-2012 Semihalf
-# All rights reserved.
-#
-# 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
-#
-# $FreeBSD$
-
-# NAND bus interface description
-#
-
-#include <sys/bus.h>
-#include <dev/nand/nand.h>
-
-INTERFACE nandbus;
-
-METHOD int get_status {
- device_t dev;
- uint8_t * status;
-};
-
-METHOD void read_buffer {
- device_t dev;
- void * buf;
- uint32_t len;
-};
-
-METHOD int select_cs {
- device_t dev;
- uint8_t cs;
-};
-
-METHOD int send_command {
- device_t dev;
- uint8_t command;
-};
-
-METHOD int send_address {
- device_t dev;
- uint8_t address;
-};
-
-METHOD int start_command {
- device_t dev;
-};
-
-METHOD int wait_ready {
- device_t dev;
- uint8_t * status;
-}
-
-METHOD void write_buffer {
- device_t dev;
- void * buf;
- uint32_t len;
-};
-
-METHOD int get_ecc {
- device_t dev;
- void * buf;
- uint32_t pagesize;
- void * ecc;
- int * needwrite;
-};
-
-METHOD int correct_ecc {
- device_t dev;
- void * buf;
- int pagesize;
- void * readecc;
- void * calcecc;
-};
-
-METHOD void lock {
- device_t dev;
-};
-
-METHOD void unlock {
- device_t dev;
-};
-
diff --git a/sys/dev/nand/nandsim.c b/sys/dev/nand/nandsim.c
deleted file mode 100644
index 50e4f8bb2e33..000000000000
--- a/sys/dev/nand/nandsim.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-/* Simulated NAND controller driver */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandsim.h>
-#include <dev/nand/nandsim_chip.h>
-#include <dev/nand/nandsim_log.h>
-#include <dev/nand/nandsim_swap.h>
-
-struct sim_param sim;
-struct sim_ctrl_conf ctrls[MAX_SIM_DEV];
-
-static struct cdev *nandsim_dev;
-static d_ioctl_t nandsim_ioctl;
-
-static void nandsim_init_sim_param(struct sim_param *);
-static int nandsim_create_ctrl(struct sim_ctrl *);
-static int nandsim_destroy_ctrl(int);
-static int nandsim_ctrl_status(struct sim_ctrl *);
-static int nandsim_create_chip(struct sim_chip *);
-static int nandsim_destroy_chip(struct sim_ctrl_chip *);
-static int nandsim_chip_status(struct sim_chip *);
-static int nandsim_start_ctrl(int);
-static int nandsim_stop_ctrl(int);
-static int nandsim_inject_error(struct sim_error *);
-static int nandsim_get_block_state(struct sim_block_state *);
-static int nandsim_set_block_state(struct sim_block_state *);
-static int nandsim_modify(struct sim_mod *);
-static int nandsim_dump(struct sim_dump *);
-static int nandsim_restore(struct sim_dump *);
-static int nandsim_freeze(struct sim_ctrl_chip *);
-static void nandsim_print_log(struct sim_log *);
-static struct nandsim_chip *get_nandsim_chip(uint8_t, uint8_t);
-
-static struct cdevsw nandsim_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_ioctl = nandsim_ioctl,
- .d_name = "nandsim",
-};
-
-int
-nandsim_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
- int flags, struct thread *td)
-{
- int ret = 0;
-
- switch (cmd) {
- case NANDSIM_SIM_PARAM:
- nandsim_init_sim_param((struct sim_param *)data);
- break;
- case NANDSIM_CREATE_CTRL:
- ret = nandsim_create_ctrl((struct sim_ctrl *)data);
- break;
- case NANDSIM_DESTROY_CTRL:
- ret = nandsim_destroy_ctrl(*(int *)data);
- break;
- case NANDSIM_STATUS_CTRL:
- ret = nandsim_ctrl_status((struct sim_ctrl *)data);
- break;
- case NANDSIM_CREATE_CHIP:
- ret = nandsim_create_chip((struct sim_chip *)data);
- break;
- case NANDSIM_DESTROY_CHIP:
- ret = nandsim_destroy_chip((struct sim_ctrl_chip *)data);
- break;
- case NANDSIM_STATUS_CHIP:
- ret = nandsim_chip_status((struct sim_chip *)data);
- break;
- case NANDSIM_MODIFY:
- ret = nandsim_modify((struct sim_mod *)data);
- break;
- case NANDSIM_START_CTRL:
- ret = nandsim_start_ctrl(*(int *)data);
- break;
- case NANDSIM_STOP_CTRL:
- ret = nandsim_stop_ctrl(*(int *)data);
- break;
- case NANDSIM_INJECT_ERROR:
- ret = nandsim_inject_error((struct sim_error *)data);
- break;
- case NANDSIM_SET_BLOCK_STATE:
- ret = nandsim_set_block_state((struct sim_block_state *)data);
- break;
- case NANDSIM_GET_BLOCK_STATE:
- ret = nandsim_get_block_state((struct sim_block_state *)data);
- break;
- case NANDSIM_PRINT_LOG:
- nandsim_print_log((struct sim_log *)data);
- break;
- case NANDSIM_DUMP:
- ret = nandsim_dump((struct sim_dump *)data);
- break;
- case NANDSIM_RESTORE:
- ret = nandsim_restore((struct sim_dump *)data);
- break;
- case NANDSIM_FREEZE:
- ret = nandsim_freeze((struct sim_ctrl_chip *)data);
- break;
- default:
- ret = EINVAL;
- break;
- }
-
- return (ret);
-}
-
-static void
-nandsim_init_sim_param(struct sim_param *param)
-{
-
- if (!param)
- return;
-
- nand_debug(NDBG_SIM,"log level:%d output %d", param->log_level,
- param->log_output);
- nandsim_log_level = param->log_level;
- nandsim_log_output = param->log_output;
-}
-
-static int
-nandsim_create_ctrl(struct sim_ctrl *ctrl)
-{
- struct sim_ctrl_conf *sim_ctrl;
-
- nand_debug(NDBG_SIM,"create controller num:%d cs:%d",ctrl->num,
- ctrl->num_cs);
-
- if (ctrl->num >= MAX_SIM_DEV) {
- return (EINVAL);
- }
-
- sim_ctrl = &ctrls[ctrl->num];
- if(sim_ctrl->created)
- return (EEXIST);
-
- sim_ctrl->num = ctrl->num;
- sim_ctrl->num_cs = ctrl->num_cs;
- sim_ctrl->ecc = ctrl->ecc;
- memcpy(sim_ctrl->ecc_layout, ctrl->ecc_layout,
- MAX_ECC_BYTES * sizeof(ctrl->ecc_layout[0]));
- strlcpy(sim_ctrl->filename, ctrl->filename,
- FILENAME_SIZE);
- sim_ctrl->created = 1;
-
- return (0);
-}
-
-static int
-nandsim_destroy_ctrl(int ctrl_num)
-{
-
- nand_debug(NDBG_SIM,"destroy controller num:%d", ctrl_num);
-
- if (ctrl_num >= MAX_SIM_DEV) {
- return (EINVAL);
- }
-
- if (!ctrls[ctrl_num].created) {
- return (ENODEV);
- }
-
- if (ctrls[ctrl_num].running) {
- return (EBUSY);
- }
-
- memset(&ctrls[ctrl_num], 0, sizeof(ctrls[ctrl_num]));
-
- return (0);
-}
-
-static int
-nandsim_ctrl_status(struct sim_ctrl *ctrl)
-{
-
- nand_debug(NDBG_SIM,"status controller num:%d cs:%d",ctrl->num,
- ctrl->num_cs);
-
- if (ctrl->num >= MAX_SIM_DEV) {
- return (EINVAL);
- }
-
- ctrl->num_cs = ctrls[ctrl->num].num_cs;
- ctrl->ecc = ctrls[ctrl->num].ecc;
- memcpy(ctrl->ecc_layout, ctrls[ctrl->num].ecc_layout,
- MAX_ECC_BYTES * sizeof(ctrl->ecc_layout[0]));
- strlcpy(ctrl->filename, ctrls[ctrl->num].filename,
- FILENAME_SIZE);
- ctrl->running = ctrls[ctrl->num].running;
- ctrl->created = ctrls[ctrl->num].created;
-
- return (0);
-}
-
-static int
-nandsim_create_chip(struct sim_chip *chip)
-{
- struct sim_chip *sim_chip;
-
- nand_debug(NDBG_SIM,"create chip num:%d at ctrl:%d", chip->num,
- chip->ctrl_num);
-
- if (chip->ctrl_num >= MAX_SIM_DEV ||
- chip->num >= MAX_CTRL_CS) {
- return (EINVAL);
- }
-
- if (ctrls[chip->ctrl_num].chips[chip->num]) {
- return (EEXIST);
- }
-
- sim_chip = malloc(sizeof(*sim_chip), M_NANDSIM,
- M_WAITOK);
- if (sim_chip == NULL) {
- return (ENOMEM);
- }
-
- memcpy(sim_chip, chip, sizeof(*sim_chip));
- ctrls[chip->ctrl_num].chips[chip->num] = sim_chip;
- sim_chip->created = 1;
-
- return (0);
-}
-
-static int
-nandsim_destroy_chip(struct sim_ctrl_chip *chip)
-{
- struct sim_ctrl_conf *ctrl_conf;
-
- nand_debug(NDBG_SIM,"destroy chip num:%d at ctrl:%d", chip->chip_num,
- chip->ctrl_num);
-
- if (chip->ctrl_num >= MAX_SIM_DEV ||
- chip->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- ctrl_conf = &ctrls[chip->ctrl_num];
-
- if (!ctrl_conf->created || !ctrl_conf->chips[chip->chip_num])
- return (ENODEV);
-
- if (ctrl_conf->running)
- return (EBUSY);
-
- free(ctrl_conf->chips[chip->chip_num], M_NANDSIM);
- ctrl_conf->chips[chip->chip_num] = NULL;
-
- return (0);
-}
-
-static int
-nandsim_chip_status(struct sim_chip *chip)
-{
- struct sim_ctrl_conf *ctrl_conf;
-
- nand_debug(NDBG_SIM,"status for chip num:%d at ctrl:%d", chip->num,
- chip->ctrl_num);
-
- if (chip->ctrl_num >= MAX_SIM_DEV ||
- chip->num >= MAX_CTRL_CS)
- return (EINVAL);
-
- ctrl_conf = &ctrls[chip->ctrl_num];
- if (!ctrl_conf->chips[chip->num])
- chip->created = 0;
- else
- memcpy(chip, ctrl_conf->chips[chip->num], sizeof(*chip));
-
- return (0);
-}
-
-static int
-nandsim_start_ctrl(int num)
-{
- device_t nexus, ndev;
- devclass_t nexus_devclass;
- int ret = 0;
-
- nand_debug(NDBG_SIM,"start ctlr num:%d", num);
-
- if (num >= MAX_SIM_DEV)
- return (EINVAL);
-
- if (!ctrls[num].created)
- return (ENODEV);
-
- if (ctrls[num].running)
- return (EBUSY);
-
- /* We will add our device as a child of the nexus0 device */
- if (!(nexus_devclass = devclass_find("nexus")) ||
- !(nexus = devclass_get_device(nexus_devclass, 0)))
- return (EFAULT);
-
- /*
- * Create a newbus device representing this frontend instance
- *
- * XXX powerpc nexus doesn't implement bus_add_child, so child
- * must be added by device_add_child().
- */
-#if defined(__powerpc__)
- ndev = device_add_child(nexus, "nandsim", num);
-#else
- ndev = BUS_ADD_CHILD(nexus, 0, "nandsim", num);
-#endif
- if (!ndev)
- return (EFAULT);
-
- mtx_lock(&Giant);
- ret = device_probe_and_attach(ndev);
- mtx_unlock(&Giant);
-
- if (ret == 0) {
- ctrls[num].sim_ctrl_dev = ndev;
- ctrls[num].running = 1;
- }
-
- return (ret);
-}
-
-static int
-nandsim_stop_ctrl(int num)
-{
- device_t nexus;
- devclass_t nexus_devclass;
- int ret = 0;
-
- nand_debug(NDBG_SIM,"stop controller num:%d", num);
-
- if (num >= MAX_SIM_DEV) {
- return (EINVAL);
- }
-
- if (!ctrls[num].created || !ctrls[num].running) {
- return (ENODEV);
- }
-
- /* We will add our device as a child of the nexus0 device */
- if (!(nexus_devclass = devclass_find("nexus")) ||
- !(nexus = devclass_get_device(nexus_devclass, 0))) {
- return (ENODEV);
- }
-
- mtx_lock(&Giant);
- if (ctrls[num].sim_ctrl_dev) {
- ret = device_delete_child(nexus, ctrls[num].sim_ctrl_dev);
- ctrls[num].sim_ctrl_dev = NULL;
- }
- mtx_unlock(&Giant);
-
- ctrls[num].running = 0;
-
- return (ret);
-}
-
-static struct nandsim_chip *
-get_nandsim_chip(uint8_t ctrl_num, uint8_t chip_num)
-{
- struct nandsim_softc *sc;
-
- if (!ctrls[ctrl_num].sim_ctrl_dev)
- return (NULL);
-
- sc = device_get_softc(ctrls[ctrl_num].sim_ctrl_dev);
- return (sc->chips[chip_num]);
-}
-
-static void
-nandsim_print_log(struct sim_log *sim_log)
-{
- struct nandsim_softc *sc;
- int len1, len2;
-
- if (!ctrls[sim_log->ctrl_num].sim_ctrl_dev)
- return;
-
- sc = device_get_softc(ctrls[sim_log->ctrl_num].sim_ctrl_dev);
- if (sc->log_buff) {
- len1 = strlen(&sc->log_buff[sc->log_idx + 1]);
- if (len1 >= sim_log->len)
- len1 = sim_log->len;
- copyout(&sc->log_buff[sc->log_idx + 1], sim_log->log, len1);
- len2 = strlen(sc->log_buff);
- if (len2 >= (sim_log->len - len1))
- len2 = (sim_log->len - len1);
- copyout(sc->log_buff, &sim_log->log[len1], len2);
- sim_log->len = len1 + len2;
- }
-}
-
-static int
-nandsim_inject_error(struct sim_error *error)
-{
- struct nandsim_chip *chip;
- struct block_space *bs;
- struct onfi_params *param;
- int page, page_size, block, offset;
-
- nand_debug(NDBG_SIM,"inject error for chip %d at ctrl %d\n",
- error->chip_num, error->ctrl_num);
-
- if (error->ctrl_num >= MAX_SIM_DEV ||
- error->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- if (!ctrls[error->ctrl_num].created || !ctrls[error->ctrl_num].running)
- return (ENODEV);
-
- chip = get_nandsim_chip(error->ctrl_num, error->chip_num);
- param = &chip->params;
- page_size = param->bytes_per_page + param->spare_bytes_per_page;
- block = error->page_num / param->pages_per_block;
- page = error->page_num % param->pages_per_block;
-
- bs = get_bs(chip->swap, block, 1);
- if (!bs)
- return (EINVAL);
-
- offset = (page * page_size) + error->column;
- memset(&bs->blk_ptr[offset], error->pattern, error->len);
-
- return (0);
-}
-
-static int
-nandsim_set_block_state(struct sim_block_state *bs)
-{
- struct onfi_params *params;
- struct nandsim_chip *chip;
- int blocks;
-
- nand_debug(NDBG_SIM,"set block state for %d:%d block %d\n",
- bs->chip_num, bs->ctrl_num, bs->block_num);
-
- if (bs->ctrl_num >= MAX_SIM_DEV ||
- bs->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- chip = get_nandsim_chip(bs->ctrl_num, bs->chip_num);
- params = &chip->params;
- blocks = params->luns * params->blocks_per_lun;
-
- if (bs->block_num > blocks)
- return (EINVAL);
-
- chip->blk_state[bs->block_num].is_bad = bs->state;
-
- if (bs->wearout >= 0)
- chip->blk_state[bs->block_num].wear_lev = bs->wearout;
-
- return (0);
-}
-
-static int
-nandsim_get_block_state(struct sim_block_state *bs)
-{
- struct onfi_params *params;
- struct nandsim_chip *chip;
- int blocks;
-
- if (bs->ctrl_num >= MAX_SIM_DEV ||
- bs->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- nand_debug(NDBG_SIM,"get block state for %d:%d block %d\n",
- bs->chip_num, bs->ctrl_num, bs->block_num);
-
- chip = get_nandsim_chip(bs->ctrl_num, bs->chip_num);
- params = &chip->params;
- blocks = params->luns * params->blocks_per_lun;
-
- if (bs->block_num > blocks)
- return (EINVAL);
-
- bs->state = chip->blk_state[bs->block_num].is_bad;
- bs->wearout = chip->blk_state[bs->block_num].wear_lev;
-
- return (0);
-}
-
-static int
-nandsim_dump(struct sim_dump *dump)
-{
- struct nandsim_chip *chip;
- struct block_space *bs;
- int blk_size;
-
- nand_debug(NDBG_SIM,"dump chip %d %d\n", dump->ctrl_num, dump->chip_num);
-
- if (dump->ctrl_num >= MAX_SIM_DEV ||
- dump->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- chip = get_nandsim_chip(dump->ctrl_num, dump->chip_num);
- blk_size = chip->cg.block_size +
- (chip->cg.oob_size * chip->cg.pgs_per_blk);
-
- bs = get_bs(chip->swap, dump->block_num, 0);
- if (!bs)
- return (EINVAL);
-
- if (dump->len > blk_size)
- dump->len = blk_size;
-
- copyout(bs->blk_ptr, dump->data, dump->len);
-
- return (0);
-}
-
-static int
-nandsim_restore(struct sim_dump *dump)
-{
- struct nandsim_chip *chip;
- struct block_space *bs;
- int blk_size;
-
- nand_debug(NDBG_SIM,"restore chip %d %d\n", dump->ctrl_num,
- dump->chip_num);
-
- if (dump->ctrl_num >= MAX_SIM_DEV ||
- dump->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- chip = get_nandsim_chip(dump->ctrl_num, dump->chip_num);
- blk_size = chip->cg.block_size +
- (chip->cg.oob_size * chip->cg.pgs_per_blk);
-
- bs = get_bs(chip->swap, dump->block_num, 1);
- if (!bs)
- return (EINVAL);
-
- if (dump->len > blk_size)
- dump->len = blk_size;
-
-
- copyin(dump->data, bs->blk_ptr, dump->len);
-
- return (0);
-}
-
-static int
-nandsim_freeze(struct sim_ctrl_chip *ctrl_chip)
-{
- struct nandsim_chip *chip;
-
- if (ctrl_chip->ctrl_num >= MAX_SIM_DEV ||
- ctrl_chip->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- chip = get_nandsim_chip(ctrl_chip->ctrl_num, ctrl_chip->chip_num);
- nandsim_chip_freeze(chip);
-
- return (0);
-}
-
-static int
-nandsim_modify(struct sim_mod *mod)
-{
- struct sim_chip *sim_conf = NULL;
- struct nandsim_chip *sim_chip = NULL;
-
- nand_debug(NDBG_SIM,"modify ctlr %d chip %d", mod->ctrl_num,
- mod->chip_num);
-
- if (mod->field != SIM_MOD_LOG_LEVEL) {
- if (mod->ctrl_num >= MAX_SIM_DEV ||
- mod->chip_num >= MAX_CTRL_CS)
- return (EINVAL);
-
- sim_conf = ctrls[mod->ctrl_num].chips[mod->chip_num];
- sim_chip = get_nandsim_chip(mod->ctrl_num, mod->chip_num);
- }
-
- switch (mod->field) {
- case SIM_MOD_LOG_LEVEL:
- nandsim_log_level = mod->new_value;
- break;
- case SIM_MOD_ERASE_TIME:
- sim_conf->erase_time = sim_chip->erase_delay = mod->new_value;
- break;
- case SIM_MOD_PROG_TIME:
- sim_conf->prog_time = sim_chip->prog_delay = mod->new_value;
- break;
- case SIM_MOD_READ_TIME:
- sim_conf->read_time = sim_chip->read_delay = mod->new_value;
- break;
- case SIM_MOD_ERROR_RATIO:
- sim_conf->error_ratio = mod->new_value;
- sim_chip->error_ratio = mod->new_value;
- break;
- default:
- break;
- }
-
- return (0);
-}
-static int
-nandsim_modevent(module_t mod __unused, int type, void *data __unused)
-{
- struct sim_ctrl_chip chip_ctrl;
- int i, j;
-
- switch (type) {
- case MOD_LOAD:
- nandsim_dev = make_dev(&nandsim_cdevsw, 0,
- UID_ROOT, GID_WHEEL, 0600, "nandsim.ioctl");
- break;
- case MOD_UNLOAD:
- for (i = 0; i < MAX_SIM_DEV; i++) {
- nandsim_stop_ctrl(i);
- chip_ctrl.ctrl_num = i;
- for (j = 0; j < MAX_CTRL_CS; j++) {
- chip_ctrl.chip_num = j;
- nandsim_destroy_chip(&chip_ctrl);
- }
- nandsim_destroy_ctrl(i);
- }
- destroy_dev(nandsim_dev);
- break;
- case MOD_SHUTDOWN:
- break;
- default:
- return (EOPNOTSUPP);
- }
- return (0);
-}
-
-DEV_MODULE(nandsim, nandsim_modevent, NULL);
-MODULE_VERSION(nandsim, 1);
-MODULE_DEPEND(nandsim, nand, 1, 1, 1);
-MODULE_DEPEND(nandsim, alq, 1, 1, 1);
diff --git a/sys/dev/nand/nandsim.h b/sys/dev/nand/nandsim.h
deleted file mode 100644
index d4b225113bfd..000000000000
--- a/sys/dev/nand/nandsim.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _NANDSIM_H_
-#define _NANDSIM_H_
-
-#include <sys/ioccom.h>
-#include <sys/types.h>
-
-#define MAX_SIM_DEV 4
-#define MAX_CTRL_CS 4
-#define MAX_ECC_BYTES 512
-#define MAX_BAD_BLOCKS 512
-#define DEV_MODEL_STR_SIZE 21
-#define MAN_STR_SIZE 13
-#define FILENAME_SIZE 20
-
-#define MAX_CHIPS (MAX_SIM_DEV*MAX_CTRL_CS)
-
-#define NANDSIM_OUTPUT_NONE 0x0
-#define NANDSIM_OUTPUT_CONSOLE 0x1
-#define NANDSIM_OUTPUT_RAM 0x2
-#define NANDSIM_OUTPUT_FILE 0x3
-
-struct sim_ctrl_chip {
- uint8_t ctrl_num;
- uint8_t chip_num;
-};
-
-#define NANDSIM_BASE 'A'
-
-struct sim_param {
- uint8_t log_level;
- uint8_t log_output;
-};
-
-#define NANDSIM_SIM_PARAM _IOW(NANDSIM_BASE, 1, struct sim_param)
-
-struct sim_ctrl {
- uint8_t running;
- uint8_t created;
- uint8_t num;
- uint8_t num_cs;
- uint8_t ecc;
- char filename[FILENAME_SIZE];
- uint16_t ecc_layout[MAX_ECC_BYTES];
-};
-#define NANDSIM_CREATE_CTRL _IOW(NANDSIM_BASE, 2, struct sim_ctrl)
-#define NANDSIM_DESTROY_CTRL _IOW(NANDSIM_BASE, 3, int)
-
-struct sim_chip {
- uint8_t num;
- uint8_t ctrl_num;
- uint8_t created;
- uint8_t device_id;
- uint8_t manufact_id;
- char device_model[DEV_MODEL_STR_SIZE];
- char manufacturer[MAN_STR_SIZE];
- uint8_t col_addr_cycles;
- uint8_t row_addr_cycles;
- uint8_t features;
- uint8_t width;
- uint32_t page_size;
- uint32_t oob_size;
- uint32_t pgs_per_blk;
- uint32_t blks_per_lun;
- uint32_t luns;
-
- uint32_t prog_time;
- uint32_t erase_time;
- uint32_t read_time;
- uint32_t ccs_time;
-
- uint32_t error_ratio;
- uint32_t wear_level;
- uint32_t bad_block_map[MAX_BAD_BLOCKS];
- uint8_t is_wp;
-};
-
-#define NANDSIM_CREATE_CHIP _IOW(NANDSIM_BASE, 3, struct sim_chip)
-
-struct sim_chip_destroy {
- uint8_t ctrl_num;
- uint8_t chip_num;
-};
-#define NANDSIM_DESTROY_CHIP _IOW(NANDSIM_BASE, 4, struct sim_chip_destroy)
-
-#define NANDSIM_START_CTRL _IOW(NANDSIM_BASE, 5, int)
-#define NANDSIM_STOP_CTRL _IOW(NANDSIM_BASE, 6, int)
-#define NANDSIM_RESTART_CTRL _IOW(NANDSIM_BASE, 7, int)
-
-#define NANDSIM_STATUS_CTRL _IOWR(NANDSIM_BASE, 8, struct sim_ctrl)
-#define NANDSIM_STATUS_CHIP _IOWR(NANDSIM_BASE, 9, struct sim_chip)
-
-struct sim_mod {
- uint8_t chip_num;
- uint8_t ctrl_num;
- uint32_t field;
- uint32_t new_value;
-};
-#define SIM_MOD_LOG_LEVEL 0
-#define SIM_MOD_ERASE_TIME 1
-#define SIM_MOD_PROG_TIME 2
-#define SIM_MOD_READ_TIME 3
-#define SIM_MOD_CCS_TIME 4
-#define SIM_MOD_ERROR_RATIO 5
-
-#define NANDSIM_MODIFY _IOW(NANDSIM_BASE, 10, struct sim_mod)
-#define NANDSIM_FREEZE _IOW(NANDSIM_BASE, 11, struct sim_ctrl_chip)
-
-struct sim_error {
- uint8_t ctrl_num;
- uint8_t chip_num;
- uint32_t page_num;
- uint32_t column;
- uint32_t len;
- uint32_t pattern;
-};
-#define NANDSIM_INJECT_ERROR _IOW(NANDSIM_BASE, 20, struct sim_error)
-
-#define NANDSIM_GOOD_BLOCK 0
-#define NANDSIM_BAD_BLOCK 1
-struct sim_block_state {
- uint8_t ctrl_num;
- uint8_t chip_num;
- uint32_t block_num;
- int wearout;
- uint8_t state;
-};
-#define NANDSIM_SET_BLOCK_STATE _IOW(NANDSIM_BASE, 21, struct sim_block_state)
-#define NANDSIM_GET_BLOCK_STATE _IOWR(NANDSIM_BASE, 22, struct sim_block_state)
-
-struct sim_log {
- uint8_t ctrl_num;
- char* log;
- size_t len;
-};
-#define NANDSIM_PRINT_LOG _IOWR(NANDSIM_BASE, 23, struct sim_log)
-
-struct sim_dump {
- uint8_t ctrl_num;
- uint8_t chip_num;
- uint32_t block_num;
- uint32_t len;
- void* data;
-};
-#define NANDSIM_DUMP _IOWR(NANDSIM_BASE, 24, struct sim_dump)
-#define NANDSIM_RESTORE _IOWR(NANDSIM_BASE, 25, struct sim_dump)
-
-#endif /* _NANDSIM_H_ */
diff --git a/sys/dev/nand/nandsim_chip.c b/sys/dev/nand/nandsim_chip.c
deleted file mode 100644
index b7ab83b9d208..000000000000
--- a/sys/dev/nand/nandsim_chip.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/sched.h>
-#include <sys/kthread.h>
-#include <sys/unistd.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandsim_chip.h>
-#include <dev/nand/nandsim_log.h>
-#include <dev/nand/nandsim_swap.h>
-
-MALLOC_DEFINE(M_NANDSIM, "NANDsim", "NANDsim dynamic data");
-
-#define NANDSIM_CHIP_LOCK(chip) mtx_lock(&(chip)->ns_lock)
-#define NANDSIM_CHIP_UNLOCK(chip) mtx_unlock(&(chip)->ns_lock)
-
-static nandsim_evh_t erase_evh;
-static nandsim_evh_t idle_evh;
-static nandsim_evh_t poweron_evh;
-static nandsim_evh_t reset_evh;
-static nandsim_evh_t read_evh;
-static nandsim_evh_t readid_evh;
-static nandsim_evh_t readparam_evh;
-static nandsim_evh_t write_evh;
-
-static void nandsim_loop(void *);
-static void nandsim_undefined(struct nandsim_chip *, uint8_t);
-static void nandsim_bad_address(struct nandsim_chip *, uint8_t *);
-static void nandsim_ignore_address(struct nandsim_chip *, uint8_t);
-static void nandsim_sm_error(struct nandsim_chip *);
-static void nandsim_start_handler(struct nandsim_chip *, nandsim_evh_t);
-
-static void nandsim_callout_eh(void *);
-static int nandsim_delay(struct nandsim_chip *, int);
-
-static int nandsim_bbm_init(struct nandsim_chip *, uint32_t, uint32_t *);
-static int nandsim_blk_state_init(struct nandsim_chip *, uint32_t, uint32_t);
-static void nandsim_blk_state_destroy(struct nandsim_chip *);
-static int nandchip_is_block_valid(struct nandsim_chip *, int);
-
-static void nandchip_set_status(struct nandsim_chip *, uint8_t);
-static void nandchip_clear_status(struct nandsim_chip *, uint8_t);
-
-struct proc *nandsim_proc;
-
-struct nandsim_chip *
-nandsim_chip_init(struct nandsim_softc* sc, uint8_t chip_num,
- struct sim_chip *sim_chip)
-{
- struct nandsim_chip *chip;
- struct onfi_params *chip_param;
- char swapfile[20];
- uint32_t size;
- int error;
-
- chip = malloc(sizeof(*chip), M_NANDSIM, M_WAITOK | M_ZERO);
-
- mtx_init(&chip->ns_lock, "nandsim lock", NULL, MTX_DEF);
- callout_init(&chip->ns_callout, 1);
- STAILQ_INIT(&chip->nandsim_events);
-
- chip->chip_num = chip_num;
- chip->ctrl_num = sim_chip->ctrl_num;
- chip->sc = sc;
-
- if (!sim_chip->is_wp)
- nandchip_set_status(chip, NAND_STATUS_WP);
-
- chip_param = &chip->params;
-
- chip->id.dev_id = sim_chip->device_id;
- chip->id.man_id = sim_chip->manufact_id;
-
- chip->error_ratio = sim_chip->error_ratio;
- chip->wear_level = sim_chip->wear_level;
- chip->prog_delay = sim_chip->prog_time;
- chip->erase_delay = sim_chip->erase_time;
- chip->read_delay = sim_chip->read_time;
-
- chip_param->t_prog = sim_chip->prog_time;
- chip_param->t_bers = sim_chip->erase_time;
- chip_param->t_r = sim_chip->read_time;
- bcopy("onfi", &chip_param->signature, 4);
-
- chip_param->manufacturer_id = sim_chip->manufact_id;
- strncpy(chip_param->manufacturer_name, sim_chip->manufacturer, 12);
- chip_param->manufacturer_name[11] = 0;
- strncpy(chip_param->device_model, sim_chip->device_model, 20);
- chip_param->device_model[19] = 0;
-
- chip_param->bytes_per_page = sim_chip->page_size;
- chip_param->spare_bytes_per_page = sim_chip->oob_size;
- chip_param->pages_per_block = sim_chip->pgs_per_blk;
- chip_param->blocks_per_lun = sim_chip->blks_per_lun;
- chip_param->luns = sim_chip->luns;
-
- init_chip_geom(&chip->cg, chip_param->luns, chip_param->blocks_per_lun,
- chip_param->pages_per_block, chip_param->bytes_per_page,
- chip_param->spare_bytes_per_page);
-
- chip_param->address_cycles = sim_chip->row_addr_cycles |
- (sim_chip->col_addr_cycles << 4);
- chip_param->features = sim_chip->features;
- if (sim_chip->width == 16)
- chip_param->features |= ONFI_FEAT_16BIT;
-
- size = chip_param->blocks_per_lun * chip_param->luns;
-
- error = nandsim_blk_state_init(chip, size, sim_chip->wear_level);
- if (error) {
- mtx_destroy(&chip->ns_lock);
- free(chip, M_NANDSIM);
- return (NULL);
- }
-
- error = nandsim_bbm_init(chip, size, sim_chip->bad_block_map);
- if (error) {
- mtx_destroy(&chip->ns_lock);
- nandsim_blk_state_destroy(chip);
- free(chip, M_NANDSIM);
- return (NULL);
- }
-
- nandsim_start_handler(chip, poweron_evh);
-
- nand_debug(NDBG_SIM,"Create thread for chip%d [%8p]", chip->chip_num,
- chip);
- /* Create chip thread */
- error = kproc_kthread_add(nandsim_loop, chip, &nandsim_proc,
- &chip->nandsim_td, RFSTOPPED | RFHIGHPID,
- 0, "nandsim", "chip");
- if (error) {
- mtx_destroy(&chip->ns_lock);
- nandsim_blk_state_destroy(chip);
- free(chip, M_NANDSIM);
- return (NULL);
- }
-
- thread_lock(chip->nandsim_td);
- sched_class(chip->nandsim_td, PRI_REALTIME);
- sched_add(chip->nandsim_td, SRQ_BORING);
- thread_unlock(chip->nandsim_td);
-
- size = (chip_param->bytes_per_page +
- chip_param->spare_bytes_per_page) *
- chip_param->pages_per_block;
-
- sprintf(swapfile, "chip%d%d.swp", chip->ctrl_num, chip->chip_num);
- chip->swap = nandsim_swap_init(swapfile, chip_param->blocks_per_lun *
- chip_param->luns, size);
- if (!chip->swap)
- nandsim_chip_destroy(chip);
-
- /* Wait for new thread to enter main loop */
- tsleep(chip->nandsim_td, PWAIT, "ns_chip", 1 * hz);
-
- return (chip);
-}
-
-static int
-nandsim_blk_state_init(struct nandsim_chip *chip, uint32_t size,
- uint32_t wear_lev)
-{
- int i;
-
- if (!chip || size == 0)
- return (-1);
-
- chip->blk_state = malloc(size * sizeof(struct nandsim_block_state),
- M_NANDSIM, M_WAITOK | M_ZERO);
-
- for (i = 0; i < size; i++) {
- if (wear_lev)
- chip->blk_state[i].wear_lev = wear_lev;
- else
- chip->blk_state[i].wear_lev = -1;
- }
-
- return (0);
-}
-
-static void
-nandsim_blk_state_destroy(struct nandsim_chip *chip)
-{
-
- if (chip && chip->blk_state)
- free(chip->blk_state, M_NANDSIM);
-}
-
-static int
-nandsim_bbm_init(struct nandsim_chip *chip, uint32_t size,
- uint32_t *sim_bbm)
-{
- uint32_t index;
- int i;
-
- if ((chip == NULL) || (size == 0))
- return (-1);
-
- if (chip->blk_state == NULL)
- return (-1);
-
- if (sim_bbm == NULL)
- return (0);
-
- for (i = 0; i < MAX_BAD_BLOCKS; i++) {
- index = sim_bbm[i];
-
- if (index == 0xffffffff)
- break;
- else if (index > size)
- return (-1);
- else
- chip->blk_state[index].is_bad = 1;
- }
-
- return (0);
-}
-
-void
-nandsim_chip_destroy(struct nandsim_chip *chip)
-{
- struct nandsim_ev *ev;
-
- ev = create_event(chip, NANDSIM_EV_EXIT, 0);
- if (ev)
- send_event(ev);
-}
-
-void
-nandsim_chip_freeze(struct nandsim_chip *chip)
-{
-
- chip->flags |= NANDSIM_CHIP_FROZEN;
-}
-
-static void
-nandsim_loop(void *arg)
-{
- struct nandsim_chip *chip = (struct nandsim_chip *)arg;
- struct nandsim_ev *ev;
-
- nand_debug(NDBG_SIM,"Start main loop for chip%d [%8p]", chip->chip_num,
- chip);
- for(;;) {
- NANDSIM_CHIP_LOCK(chip);
- if (!(chip->flags & NANDSIM_CHIP_ACTIVE)) {
- chip->flags |= NANDSIM_CHIP_ACTIVE;
- wakeup(chip->nandsim_td);
- }
-
- if (STAILQ_EMPTY(&chip->nandsim_events)) {
- nand_debug(NDBG_SIM,"Chip%d [%8p] going sleep",
- chip->chip_num, chip);
- msleep(chip, &chip->ns_lock, PRIBIO, "nandev", 0);
- }
-
- ev = STAILQ_FIRST(&chip->nandsim_events);
- STAILQ_REMOVE_HEAD(&chip->nandsim_events, links);
- NANDSIM_CHIP_UNLOCK(chip);
- if (ev->type == NANDSIM_EV_EXIT) {
- NANDSIM_CHIP_LOCK(chip);
- destroy_event(ev);
- wakeup(ev);
- while (!STAILQ_EMPTY(&chip->nandsim_events)) {
- ev = STAILQ_FIRST(&chip->nandsim_events);
- STAILQ_REMOVE_HEAD(&chip->nandsim_events,
- links);
- destroy_event(ev);
- wakeup(ev);
- }
- NANDSIM_CHIP_UNLOCK(chip);
- nandsim_log(chip, NANDSIM_LOG_SM, "destroyed\n");
- mtx_destroy(&chip->ns_lock);
- nandsim_blk_state_destroy(chip);
- nandsim_swap_destroy(chip->swap);
- free(chip, M_NANDSIM);
- nandsim_proc = NULL;
-
- kthread_exit();
- }
-
- if (!(chip->flags & NANDSIM_CHIP_FROZEN)) {
- nand_debug(NDBG_SIM,"Chip [%x] get event [%x]",
- chip->chip_num, ev->type);
- chip->ev_handler(chip, ev->type, ev->data);
- }
-
- wakeup(ev);
- destroy_event(ev);
- }
-
-}
-
-struct nandsim_ev *
-create_event(struct nandsim_chip *chip, uint8_t type, uint8_t data_size)
-{
- struct nandsim_ev *ev;
-
- ev = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO);
- if (!ev) {
- nand_debug(NDBG_SIM,"Cannot create event");
- return (NULL);
- }
-
- if (data_size > 0)
- ev->data = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO);
- ev->type = type;
- ev->chip = chip;
-
- return (ev);
-}
-
-void
-destroy_event(struct nandsim_ev *ev)
-{
-
- if (ev->data)
- free(ev->data, M_NANDSIM);
- free(ev, M_NANDSIM);
-}
-
-int
-send_event(struct nandsim_ev *ev)
-{
- struct nandsim_chip *chip = ev->chip;
-
- if (!(chip->flags & NANDSIM_CHIP_FROZEN)) {
- nand_debug(NDBG_SIM,"Chip%d [%p] send event %x",
- chip->chip_num, chip, ev->type);
-
- NANDSIM_CHIP_LOCK(chip);
- STAILQ_INSERT_TAIL(&chip->nandsim_events, ev, links);
- NANDSIM_CHIP_UNLOCK(chip);
-
- wakeup(chip);
- if ((ev->type != NANDSIM_EV_TIMEOUT) && chip->nandsim_td &&
- (curthread != chip->nandsim_td))
- tsleep(ev, PWAIT, "ns_ev", 5 * hz);
- }
-
- return (0);
-}
-
-static void
-nandsim_callout_eh(void *arg)
-{
- struct nandsim_ev *ev = (struct nandsim_ev *)arg;
-
- send_event(ev);
-}
-
-static int
-nandsim_delay(struct nandsim_chip *chip, int timeout)
-{
- struct nandsim_ev *ev;
- struct timeval delay;
- int tm;
-
- nand_debug(NDBG_SIM,"Chip[%d] Set delay: %d", chip->chip_num, timeout);
-
- ev = create_event(chip, NANDSIM_EV_TIMEOUT, 0);
- if (!ev)
- return (-1);
-
- chip->sm_state = NANDSIM_STATE_TIMEOUT;
- tm = (timeout/10000) * (hz / 100);
- if (callout_reset(&chip->ns_callout, tm, nandsim_callout_eh, ev))
- return (-1);
-
- delay.tv_sec = chip->read_delay / 1000000;
- delay.tv_usec = chip->read_delay % 1000000;
- timevaladd(&chip->delay_tv, &delay);
-
- return (0);
-}
-
-static void
-nandsim_start_handler(struct nandsim_chip *chip, nandsim_evh_t evh)
-{
- struct nandsim_ev *ev;
-
- chip->ev_handler = evh;
-
- nand_debug(NDBG_SIM,"Start handler %p for chip%d [%p]", evh,
- chip->chip_num, chip);
- ev = create_event(chip, NANDSIM_EV_START, 0);
- if (!ev)
- nandsim_sm_error(chip);
-
- send_event(ev);
-}
-
-static void
-nandchip_set_data(struct nandsim_chip *chip, uint8_t *data, uint32_t len,
- uint32_t idx)
-{
-
- nand_debug(NDBG_SIM,"Chip [%x] data %p [%x] at %x", chip->chip_num,
- data, len, idx);
- chip->data.data_ptr = data;
- chip->data.size = len;
- chip->data.index = idx;
-}
-
-static int
-nandchip_chip_space(struct nandsim_chip *chip, int32_t row, int32_t column,
- size_t size, uint8_t writing)
-{
- struct block_space *blk_space;
- uint32_t lun, block, page, offset, block_size;
- int err;
-
- block_size = chip->cg.block_size +
- (chip->cg.oob_size * chip->cg.pgs_per_blk);
-
- err = nand_row_to_blkpg(&chip->cg, row, &lun, &block, &page);
- if (err) {
- nand_debug(NDBG_SIM,"cannot get address\n");
- return (-1);
- }
-
- if (!nandchip_is_block_valid(chip, block)) {
- nandchip_set_data(chip, NULL, 0, 0);
- return (-1);
- }
-
- blk_space = get_bs(chip->swap, block, writing);
- if (!blk_space) {
- nandchip_set_data(chip, NULL, 0, 0);
- return (-1);
- }
-
- if (size > block_size)
- size = block_size;
-
- if (size == block_size) {
- offset = 0;
- column = 0;
- } else
- offset = page * (chip->cg.page_size + chip->cg.oob_size);
-
- nandchip_set_data(chip, &blk_space->blk_ptr[offset], size, column);
-
- return (0);
-}
-
-static int
-nandchip_get_addr_byte(struct nandsim_chip *chip, void *data, uint32_t *value)
-{
- int ncycles = 0;
- uint8_t byte;
- uint8_t *buffer;
-
- buffer = (uint8_t *)value;
- byte = *((uint8_t *)data);
-
- KASSERT((chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW ||
- chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL),
- ("unexpected state"));
-
- if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
- ncycles = chip->params.address_cycles & 0xf;
- buffer[chip->sm_addr_cycle++] = byte;
- } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) {
- ncycles = (chip->params.address_cycles >> 4) & 0xf;
- buffer[chip->sm_addr_cycle++] = byte;
- }
-
- nand_debug(NDBG_SIM, "Chip [%x] read addr byte: %02x (%d of %d)\n",
- chip->chip_num, byte, chip->sm_addr_cycle, ncycles);
-
- if (chip->sm_addr_cycle == ncycles) {
- chip->sm_addr_cycle = 0;
- return (0);
- }
-
- return (1);
-}
-
-static int
-nandchip_is_block_valid(struct nandsim_chip *chip, int block_num)
-{
-
- if (!chip || !chip->blk_state)
- return (0);
-
- if (chip->blk_state[block_num].wear_lev == 0 ||
- chip->blk_state[block_num].is_bad)
- return (0);
-
- return (1);
-}
-
-static void
-nandchip_set_status(struct nandsim_chip *chip, uint8_t flags)
-{
-
- chip->chip_status |= flags;
-}
-
-static void
-nandchip_clear_status(struct nandsim_chip *chip, uint8_t flags)
-{
-
- chip->chip_status &= ~flags;
-}
-
-uint8_t
-nandchip_get_status(struct nandsim_chip *chip)
-{
- return (chip->chip_status);
-}
-
-void
-nandsim_chip_timeout(struct nandsim_chip *chip)
-{
- struct timeval tv;
-
- getmicrotime(&tv);
-
- if (chip->sm_state == NANDSIM_STATE_TIMEOUT &&
- timevalcmp(&tv, &chip->delay_tv, >=)) {
- nandchip_set_status(chip, NAND_STATUS_RDY);
- }
-}
-void
-poweron_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
- uint8_t cmd;
-
- if (type == NANDSIM_EV_START)
- chip->sm_state = NANDSIM_STATE_IDLE;
- else if (type == NANDSIM_EV_CMD) {
- cmd = *(uint8_t *)data;
- switch(cmd) {
- case NAND_CMD_RESET:
- nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n");
- nandsim_start_handler(chip, reset_evh);
- break;
- default:
- nandsim_undefined(chip, type);
- break;
- }
- } else
- nandsim_undefined(chip, type);
-}
-
-void
-idle_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
- uint8_t cmd;
-
- if (type == NANDSIM_EV_START) {
- nandsim_log(chip, NANDSIM_LOG_SM, "in IDLE state\n");
- chip->sm_state = NANDSIM_STATE_WAIT_CMD;
- } else if (type == NANDSIM_EV_CMD) {
- nandchip_clear_status(chip, NAND_STATUS_FAIL);
- getmicrotime(&chip->delay_tv);
- cmd = *(uint8_t *)data;
- switch(cmd) {
- case NAND_CMD_READ_ID:
- nandsim_start_handler(chip, readid_evh);
- break;
- case NAND_CMD_READ_PARAMETER:
- nandsim_start_handler(chip, readparam_evh);
- break;
- case NAND_CMD_READ:
- nandsim_start_handler(chip, read_evh);
- break;
- case NAND_CMD_PROG:
- nandsim_start_handler(chip, write_evh);
- break;
- case NAND_CMD_ERASE:
- nandsim_start_handler(chip, erase_evh);
- break;
- default:
- nandsim_undefined(chip, type);
- break;
- }
- } else
- nandsim_undefined(chip, type);
-}
-
-void
-readid_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
- struct onfi_params *params;
- uint8_t addr;
-
- params = &chip->params;
-
- if (type == NANDSIM_EV_START) {
- nandsim_log(chip, NANDSIM_LOG_SM, "in READID state\n");
- chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE;
- } else if (type == NANDSIM_EV_ADDR) {
-
- addr = *((uint8_t *)data);
-
- if (addr == 0x0)
- nandchip_set_data(chip, (uint8_t *)&chip->id, 2, 0);
- else if (addr == ONFI_SIG_ADDR)
- nandchip_set_data(chip, (uint8_t *)&params->signature,
- 4, 0);
- else
- nandsim_bad_address(chip, &addr);
-
- nandsim_start_handler(chip, idle_evh);
- } else
- nandsim_undefined(chip, type);
-}
-
-void
-readparam_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
- struct onfi_params *params;
- uint8_t addr;
-
- params = &chip->params;
-
- if (type == NANDSIM_EV_START) {
- nandsim_log(chip, NANDSIM_LOG_SM, "in READPARAM state\n");
- chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE;
- } else if (type == NANDSIM_EV_ADDR) {
- addr = *((uint8_t *)data);
-
- if (addr == 0) {
- nandchip_set_data(chip, (uint8_t *)params,
- sizeof(*params), 0);
- } else
- nandsim_bad_address(chip, &addr);
-
- nandsim_start_handler(chip, idle_evh);
- } else
- nandsim_undefined(chip, type);
-}
-
-void
-read_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
- static uint32_t column = 0, row = 0;
- uint32_t size;
- uint8_t cmd;
-
- size = chip->cg.page_size + chip->cg.oob_size;
-
- switch (type) {
- case NANDSIM_EV_START:
- nandsim_log(chip, NANDSIM_LOG_SM, "in READ state\n");
- chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL;
- break;
- case NANDSIM_EV_ADDR:
- if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) {
- if (nandchip_get_addr_byte(chip, data, &column))
- break;
-
- chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW;
- } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
- if (nandchip_get_addr_byte(chip, data, &row))
- break;
-
- chip->sm_state = NANDSIM_STATE_WAIT_CMD;
- } else
- nandsim_ignore_address(chip, *((uint8_t *)data));
- break;
- case NANDSIM_EV_CMD:
- cmd = *(uint8_t *)data;
- if (chip->sm_state == NANDSIM_STATE_WAIT_CMD &&
- cmd == NAND_CMD_READ_END) {
- if (chip->read_delay != 0 &&
- nandsim_delay(chip, chip->read_delay) == 0)
- nandchip_clear_status(chip, NAND_STATUS_RDY);
- else {
- nandchip_chip_space(chip, row, column, size, 0);
- nandchip_set_status(chip, NAND_STATUS_RDY);
- nandsim_start_handler(chip, idle_evh);
- }
- } else
- nandsim_undefined(chip, type);
- break;
- case NANDSIM_EV_TIMEOUT:
- if (chip->sm_state == NANDSIM_STATE_TIMEOUT) {
- nandchip_chip_space(chip, row, column, size, 0);
- nandchip_set_status(chip, NAND_STATUS_RDY);
- nandsim_start_handler(chip, idle_evh);
- } else
- nandsim_undefined(chip, type);
- break;
- }
-}
-void
-write_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
- static uint32_t column, row;
- uint32_t size;
- uint8_t cmd;
- int err;
-
- size = chip->cg.page_size + chip->cg.oob_size;
-
- switch(type) {
- case NANDSIM_EV_START:
- nandsim_log(chip, NANDSIM_LOG_SM, "in WRITE state\n");
- chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL;
- break;
- case NANDSIM_EV_ADDR:
- if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) {
- if (nandchip_get_addr_byte(chip, data, &column))
- break;
-
- chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW;
- } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
- if (nandchip_get_addr_byte(chip, data, &row))
- break;
-
- err = nandchip_chip_space(chip, row, column, size, 1);
- if (err == -1)
- nandchip_set_status(chip, NAND_STATUS_FAIL);
-
- chip->sm_state = NANDSIM_STATE_WAIT_CMD;
- } else
- nandsim_ignore_address(chip, *((uint8_t *)data));
- break;
- case NANDSIM_EV_CMD:
- cmd = *(uint8_t *)data;
- if (chip->sm_state == NANDSIM_STATE_WAIT_CMD &&
- cmd == NAND_CMD_PROG_END) {
- if (chip->prog_delay != 0 &&
- nandsim_delay(chip, chip->prog_delay) == 0)
- nandchip_clear_status(chip, NAND_STATUS_RDY);
- else {
- nandchip_set_status(chip, NAND_STATUS_RDY);
- nandsim_start_handler(chip, idle_evh);
- }
- } else
- nandsim_undefined(chip, type);
- break;
- case NANDSIM_EV_TIMEOUT:
- if (chip->sm_state == NANDSIM_STATE_TIMEOUT) {
- nandsim_start_handler(chip, idle_evh);
- nandchip_set_status(chip, NAND_STATUS_RDY);
- } else
- nandsim_undefined(chip, type);
- break;
- }
-}
-
-void
-erase_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
- static uint32_t row, block_size;
- uint32_t lun, block, page;
- int err;
- uint8_t cmd;
-
- block_size = chip->cg.block_size +
- (chip->cg.oob_size * chip->cg.pgs_per_blk);
-
- switch (type) {
- case NANDSIM_EV_START:
- nandsim_log(chip, NANDSIM_LOG_SM, "in ERASE state\n");
- chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW;
- break;
- case NANDSIM_EV_CMD:
- cmd = *(uint8_t *)data;
- if (chip->sm_state == NANDSIM_STATE_WAIT_CMD &&
- cmd == NAND_CMD_ERASE_END) {
- if (chip->data.data_ptr != NULL &&
- chip->data.size == block_size)
- memset(chip->data.data_ptr, 0xff, block_size);
- else
- nand_debug(NDBG_SIM,"Bad block erase data\n");
-
- err = nand_row_to_blkpg(&chip->cg, row, &lun,
- &block, &page);
- if (!err) {
- if (chip->blk_state[block].wear_lev > 0)
- chip->blk_state[block].wear_lev--;
- }
-
- if (chip->erase_delay != 0 &&
- nandsim_delay(chip, chip->erase_delay) == 0)
- nandchip_clear_status(chip, NAND_STATUS_RDY);
- else {
- nandchip_set_status(chip, NAND_STATUS_RDY);
- nandsim_start_handler(chip, idle_evh);
- }
- } else
- nandsim_undefined(chip, type);
- break;
- case NANDSIM_EV_ADDR:
- if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
- if (nandchip_get_addr_byte(chip, data, &row))
- break;
-
- err = nandchip_chip_space(chip, row, 0, block_size, 1);
- if (err == -1) {
- nandchip_set_status(chip, NAND_STATUS_FAIL);
- }
- chip->sm_state = NANDSIM_STATE_WAIT_CMD;
- } else
- nandsim_ignore_address(chip, *((uint8_t *)data));
- break;
- case NANDSIM_EV_TIMEOUT:
- if (chip->sm_state == NANDSIM_STATE_TIMEOUT) {
- nandchip_set_status(chip, NAND_STATUS_RDY);
- nandsim_start_handler(chip, idle_evh);
- } else
- nandsim_undefined(chip, type);
- break;
- }
-}
-
-void
-reset_evh(struct nandsim_chip *chip, uint32_t type, void *data)
-{
-
- if (type == NANDSIM_EV_START) {
- nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n");
- chip->sm_state = NANDSIM_STATE_TIMEOUT;
- nandchip_set_data(chip, NULL, 0, 0);
- DELAY(500);
- nandsim_start_handler(chip, idle_evh);
- } else
- nandsim_undefined(chip, type);
-}
-
-static void
-nandsim_undefined(struct nandsim_chip *chip, uint8_t type)
-{
-
- nandsim_log(chip, NANDSIM_LOG_ERR,
- "ERR: Chip received ev %x in state %x\n",
- type, chip->sm_state);
- nandsim_start_handler(chip, idle_evh);
-}
-
-static void
-nandsim_bad_address(struct nandsim_chip *chip, uint8_t *addr)
-{
-
- nandsim_log(chip, NANDSIM_LOG_ERR,
- "ERR: Chip received out of range address"
- "%02x%02x - %02x%02x%02x\n", addr[0], addr[1], addr[2],
- addr[3], addr[4]);
-}
-
-static void
-nandsim_ignore_address(struct nandsim_chip *chip, uint8_t byte)
-{
- nandsim_log(chip, NANDSIM_LOG_SM, "ignored address byte: %d\n", byte);
-}
-
-static void
-nandsim_sm_error(struct nandsim_chip *chip)
-{
-
- nandsim_log(chip, NANDSIM_LOG_ERR, "ERR: State machine error."
- "Restart required.\n");
-}
diff --git a/sys/dev/nand/nandsim_chip.h b/sys/dev/nand/nandsim_chip.h
deleted file mode 100644
index 86ced5ea2bf2..000000000000
--- a/sys/dev/nand/nandsim_chip.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _NANDSIM_CHIP_H
-#define _NANDSIM_CHIP_H
-
-#include <sys/malloc.h>
-#include <sys/callout.h>
-#include <dev/nand/nand.h>
-#include <dev/nand/nandsim.h>
-#include <dev/nand/nandsim_swap.h>
-
-MALLOC_DECLARE(M_NANDSIM);
-
-#define MAX_CS_NUM 4
-struct nandsim_chip;
-
-typedef void nandsim_evh_t(struct nandsim_chip *chip, uint32_t ev, void *data);
-
-enum addr_type {
- ADDR_NONE,
- ADDR_ID,
- ADDR_ROW,
- ADDR_ROWCOL
-};
-
-struct nandsim_softc {
- struct nand_softc nand_dev;
- device_t dev;
-
- struct nandsim_chip *chips[MAX_CS_NUM];
- struct nandsim_chip *active_chip;
-
- uint8_t address_cycle;
- enum addr_type address_type;
- int log_idx;
- char *log_buff;
- struct alq *alq;
-};
-
-struct nandsim_ev {
- STAILQ_ENTRY(nandsim_ev) links;
- struct nandsim_chip *chip;
- uint8_t type;
- void *data;
-};
-
-struct nandsim_data {
- uint8_t *data_ptr;
- uint32_t index;
- uint32_t size;
-};
-
-struct nandsim_block_state {
- int32_t wear_lev;
- uint8_t is_bad;
-};
-
-#define NANDSIM_CHIP_ACTIVE 0x1
-#define NANDSIM_CHIP_FROZEN 0x2
-#define NANDSIM_CHIP_GET_STATUS 0x4
-
-struct nandsim_chip {
- struct nandsim_softc *sc;
- struct thread *nandsim_td;
-
- STAILQ_HEAD(, nandsim_ev) nandsim_events;
- nandsim_evh_t *ev_handler;
- struct mtx ns_lock;
- struct callout ns_callout;
-
- struct chip_geom cg;
- struct nand_id id;
- struct onfi_params params;
- struct nandsim_data data;
- struct nandsim_block_state *blk_state;
-
- struct chip_swap *swap;
-
- uint32_t error_ratio;
- uint32_t wear_level;
- uint32_t sm_state;
- uint32_t sm_addr_cycle;
-
- uint32_t erase_delay;
- uint32_t prog_delay;
- uint32_t read_delay;
- struct timeval delay_tv;
-
- uint8_t flags;
- uint8_t chip_status;
- uint8_t ctrl_num;
- uint8_t chip_num;
-};
-
-struct sim_ctrl_conf {
- uint8_t num;
- uint8_t num_cs;
- uint8_t ecc;
- uint8_t running;
- uint8_t created;
- device_t sim_ctrl_dev;
- struct sim_chip *chips[MAX_CTRL_CS];
- uint16_t ecc_layout[MAX_ECC_BYTES];
- char filename[FILENAME_SIZE];
-};
-
-#define NANDSIM_STATE_IDLE 0x0
-#define NANDSIM_STATE_WAIT_ADDR_BYTE 0x1
-#define NANDSIM_STATE_WAIT_CMD 0x2
-#define NANDSIM_STATE_TIMEOUT 0x3
-#define NANDSIM_STATE_WAIT_ADDR_ROW 0x4
-#define NANDSIM_STATE_WAIT_ADDR_COL 0x5
-
-#define NANDSIM_EV_START 0x1
-#define NANDSIM_EV_CMD 0x2
-#define NANDSIM_EV_ADDR 0x3
-#define NANDSIM_EV_TIMEOUT 0x4
-#define NANDSIM_EV_EXIT 0xff
-
-struct nandsim_chip *nandsim_chip_init(struct nandsim_softc *,
- uint8_t, struct sim_chip *);
-void nandsim_chip_destroy(struct nandsim_chip *);
-void nandsim_chip_freeze(struct nandsim_chip *);
-void nandsim_chip_timeout(struct nandsim_chip *);
-int nandsim_chip_check_bad_block(struct nandsim_chip *, int);
-
-uint8_t nandchip_get_status(struct nandsim_chip *);
-
-void destroy_event(struct nandsim_ev *);
-int send_event(struct nandsim_ev *);
-struct nandsim_ev *create_event(struct nandsim_chip *, uint8_t, uint8_t);
-
-#endif /* _NANDSIM_CHIP_H */
diff --git a/sys/dev/nand/nandsim_ctrl.c b/sys/dev/nand/nandsim_ctrl.c
deleted file mode 100644
index bc203902fe7e..000000000000
--- a/sys/dev/nand/nandsim_ctrl.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-/* Simulated NAND controller driver */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/time.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-#include <dev/nand/nandsim.h>
-#include <dev/nand/nandsim_log.h>
-#include <dev/nand/nandsim_chip.h>
-#include "nfc_if.h"
-
-#define ADDRESS_SIZE 5
-
-extern struct sim_ctrl_conf ctrls[MAX_SIM_DEV];
-
-static void byte_corrupt(struct nandsim_chip *, uint8_t *);
-
-static int nandsim_attach(device_t);
-static int nandsim_detach(device_t);
-static int nandsim_probe(device_t);
-
-static uint8_t nandsim_read_byte(device_t);
-static uint16_t nandsim_read_word(device_t);
-static int nandsim_select_cs(device_t, uint8_t);
-static void nandsim_write_byte(device_t, uint8_t);
-static void nandsim_write_word(device_t, uint16_t);
-static void nandsim_read_buf(device_t, void *, uint32_t);
-static void nandsim_write_buf(device_t, void *, uint32_t);
-static int nandsim_send_command(device_t, uint8_t);
-static int nandsim_send_address(device_t, uint8_t);
-
-static device_method_t nandsim_methods[] = {
- DEVMETHOD(device_probe, nandsim_probe),
- DEVMETHOD(device_attach, nandsim_attach),
- DEVMETHOD(device_detach, nandsim_detach),
-
- DEVMETHOD(nfc_select_cs, nandsim_select_cs),
- DEVMETHOD(nfc_send_command, nandsim_send_command),
- DEVMETHOD(nfc_send_address, nandsim_send_address),
- DEVMETHOD(nfc_read_byte, nandsim_read_byte),
- DEVMETHOD(nfc_read_word, nandsim_read_word),
- DEVMETHOD(nfc_write_byte, nandsim_write_byte),
- DEVMETHOD(nfc_read_buf, nandsim_read_buf),
- DEVMETHOD(nfc_write_buf, nandsim_write_buf),
-
- { 0, 0 },
-};
-
-static driver_t nandsim_driver = {
- "nandsim",
- nandsim_methods,
- sizeof(struct nandsim_softc),
-};
-
-static devclass_t nandsim_devclass;
-DRIVER_MODULE(nandsim, nexus, nandsim_driver, nandsim_devclass, 0, 0);
-DRIVER_MODULE(nandbus, nandsim, nandbus_driver, nandbus_devclass, 0, 0);
-
-static int
-nandsim_probe(device_t dev)
-{
-
- device_set_desc(dev, "NAND controller simulator");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-nandsim_attach(device_t dev)
-{
- struct nandsim_softc *sc;
- struct sim_ctrl_conf *params;
- struct sim_chip *chip;
- uint16_t *eccpos;
- int i, err;
-
- sc = device_get_softc(dev);
- params = &ctrls[device_get_unit(dev)];
-
- if (strlen(params->filename) == 0)
- snprintf(params->filename, FILENAME_SIZE, "ctrl%d.log",
- params->num);
-
- nandsim_log_init(sc, params->filename);
- for (i = 0; i < params->num_cs; i++) {
- chip = params->chips[i];
- if (chip && chip->device_id != 0) {
- sc->chips[i] = nandsim_chip_init(sc, i, chip);
- if (chip->features & ONFI_FEAT_16BIT)
- sc->nand_dev.flags |= NAND_16_BIT;
- }
- }
-
- if (params->ecc_layout[0] != 0xffff)
- eccpos = params->ecc_layout;
- else
- eccpos = NULL;
-
- nand_init(&sc->nand_dev, dev, params->ecc, 0, 0, eccpos, "nandsim");
-
- err = nandbus_create(dev);
-
- return (err);
-}
-
-static int
-nandsim_detach(device_t dev)
-{
- struct nandsim_softc *sc;
- struct sim_ctrl_conf *params;
- int i;
-
- sc = device_get_softc(dev);
- params = &ctrls[device_get_unit(dev)];
-
- for (i = 0; i < params->num_cs; i++)
- if (sc->chips[i] != NULL)
- nandsim_chip_destroy(sc->chips[i]);
-
- nandsim_log_close(sc);
-
- return (0);
-}
-
-static int
-nandsim_select_cs(device_t dev, uint8_t cs)
-{
- struct nandsim_softc *sc;
-
- sc = device_get_softc(dev);
-
- if (cs >= MAX_CS_NUM)
- return (EINVAL);
-
- sc->active_chip = sc->chips[cs];
-
- if (sc->active_chip)
- nandsim_log(sc->active_chip, NANDSIM_LOG_EV,
- "Select cs %d\n", cs);
-
- return (0);
-}
-
-static int
-nandsim_send_command(device_t dev, uint8_t command)
-{
- struct nandsim_softc *sc;
- struct nandsim_chip *chip;
- struct nandsim_ev *ev;
-
- sc = device_get_softc(dev);
- chip = sc->active_chip;
-
- if (chip == NULL)
- return (0);
-
- nandsim_log(chip, NANDSIM_LOG_EV, "Send command %x\n", command);
-
- switch (command) {
- case NAND_CMD_READ_ID:
- case NAND_CMD_READ_PARAMETER:
- sc->address_type = ADDR_ID;
- break;
- case NAND_CMD_ERASE:
- sc->address_type = ADDR_ROW;
- break;
- case NAND_CMD_READ:
- case NAND_CMD_PROG:
- sc->address_type = ADDR_ROWCOL;
- break;
- default:
- sc->address_type = ADDR_NONE;
- break;
- }
-
- if (command == NAND_CMD_STATUS)
- chip->flags |= NANDSIM_CHIP_GET_STATUS;
- else {
- ev = create_event(chip, NANDSIM_EV_CMD, 1);
- *(uint8_t *)ev->data = command;
- send_event(ev);
- }
-
- return (0);
-}
-
-static int
-nandsim_send_address(device_t dev, uint8_t addr)
-{
- struct nandsim_ev *ev;
- struct nandsim_softc *sc;
- struct nandsim_chip *chip;
-
- sc = device_get_softc(dev);
- chip = sc->active_chip;
-
- if (chip == NULL)
- return (0);
-
- KASSERT((sc->address_type != ADDR_NONE), ("unexpected address"));
- nandsim_log(chip, NANDSIM_LOG_EV, "Send addr %x\n", addr);
-
- ev = create_event(chip, NANDSIM_EV_ADDR, 1);
-
- *((uint8_t *)(ev->data)) = addr;
-
- send_event(ev);
- return (0);
-}
-
-static uint8_t
-nandsim_read_byte(device_t dev)
-{
- struct nandsim_softc *sc;
- struct nandsim_chip *chip;
- uint8_t ret = 0xff;
-
- sc = device_get_softc(dev);
- chip = sc->active_chip;
-
- if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) {
- if (chip->flags & NANDSIM_CHIP_GET_STATUS) {
- nandsim_chip_timeout(chip);
- ret = nandchip_get_status(chip);
- chip->flags &= ~NANDSIM_CHIP_GET_STATUS;
- } else if (chip->data.index < chip->data.size) {
- ret = chip->data.data_ptr[chip->data.index++];
- byte_corrupt(chip, &ret);
- }
- nandsim_log(chip, NANDSIM_LOG_DATA, "read %02x\n", ret);
- }
-
- return (ret);
-}
-
-static uint16_t
-nandsim_read_word(device_t dev)
-{
- struct nandsim_softc *sc;
- struct nandsim_chip *chip;
- uint16_t *data_ptr;
- uint16_t ret = 0xffff;
- uint8_t *byte_ret = (uint8_t *)&ret;
-
- sc = device_get_softc(dev);
- chip = sc->active_chip;
-
- if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) {
- if (chip->data.index < chip->data.size - 1) {
- data_ptr =
- (uint16_t *)&(chip->data.data_ptr[chip->data.index]);
- ret = *data_ptr;
- chip->data.index += 2;
- byte_corrupt(chip, byte_ret);
- byte_corrupt(chip, byte_ret + 1);
- }
- nandsim_log(chip, NANDSIM_LOG_DATA, "read %04x\n", ret);
- }
-
- return (ret);
-}
-
-static void
-nandsim_write_byte(device_t dev, uint8_t byte)
-{
- struct nandsim_softc *sc;
- struct nandsim_chip *chip;
-
- sc = device_get_softc(dev);
- chip = sc->active_chip;
-
- if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN) &&
- (chip->data.index < chip->data.size)) {
- byte_corrupt(chip, &byte);
- chip->data.data_ptr[chip->data.index] &= byte;
- chip->data.index++;
- nandsim_log(chip, NANDSIM_LOG_DATA, "write %02x\n", byte);
- }
-}
-
-static void
-nandsim_write_word(device_t dev, uint16_t word)
-{
- struct nandsim_softc *sc;
- struct nandsim_chip *chip;
- uint16_t *data_ptr;
- uint8_t *byte_ptr = (uint8_t *)&word;
-
- sc = device_get_softc(dev);
- chip = sc->active_chip;
-
- if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) {
- if ((chip->data.index + 1) < chip->data.size) {
- byte_corrupt(chip, byte_ptr);
- byte_corrupt(chip, byte_ptr + 1);
- data_ptr =
- (uint16_t *)&(chip->data.data_ptr[chip->data.index]);
- *data_ptr &= word;
- chip->data.index += 2;
- }
-
- nandsim_log(chip, NANDSIM_LOG_DATA, "write %04x\n", word);
- }
-}
-
-static void
-nandsim_read_buf(device_t dev, void *buf, uint32_t len)
-{
- struct nandsim_softc *sc;
- uint16_t *buf16 = (uint16_t *)buf;
- uint8_t *buf8 = (uint8_t *)buf;
- int i;
-
- sc = device_get_softc(dev);
-
- if (sc->nand_dev.flags & NAND_16_BIT) {
- for (i = 0; i < len / 2; i++)
- buf16[i] = nandsim_read_word(dev);
- } else {
- for (i = 0; i < len; i++)
- buf8[i] = nandsim_read_byte(dev);
- }
-}
-
-static void
-nandsim_write_buf(device_t dev, void *buf, uint32_t len)
-{
- struct nandsim_softc *sc;
- uint16_t *buf16 = (uint16_t *)buf;
- uint8_t *buf8 = (uint8_t *)buf;
- int i;
-
- sc = device_get_softc(dev);
-
- if (sc->nand_dev.flags & NAND_16_BIT) {
- for (i = 0; i < len / 2; i++)
- nandsim_write_word(dev, buf16[i]);
- } else {
- for (i = 0; i < len; i++)
- nandsim_write_byte(dev, buf8[i]);
- }
-}
-
-static void
-byte_corrupt(struct nandsim_chip *chip, uint8_t *byte)
-{
- uint32_t rand;
- uint8_t bit;
-
- rand = random();
- if ((rand % 1000000) < chip->error_ratio) {
- bit = rand % 8;
- if (*byte & (1 << bit))
- *byte &= ~(1 << bit);
- else
- *byte |= (1 << bit);
- }
-}
diff --git a/sys/dev/nand/nandsim_log.c b/sys/dev/nand/nandsim_log.c
deleted file mode 100644
index 0bd316ace4e2..000000000000
--- a/sys/dev/nand/nandsim_log.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/alq.h>
-#include <sys/time.h>
-
-#include <machine/stdarg.h>
-
-#include <dev/nand/nandsim_log.h>
-
-int nandsim_log_level;
-int nandsim_log_output;
-int log_size = NANDSIM_RAM_LOG_SIZE;
-
-static int nandsim_entry_size = NANDSIM_ENTRY_SIZE;
-static int nandsim_entry_count = NANDSIM_ENTRY_COUNT;
-static int str_index = 0;
-static char string[NANDSIM_ENTRY_SIZE + 1] = {0};
-
-int
-nandsim_log_init(struct nandsim_softc *sc, char *filename)
-{
- int error = 0;
-
- if (nandsim_log_output == NANDSIM_OUTPUT_FILE) {
- error = alq_open(&sc->alq, filename,
- curthread->td_ucred, 0644,
- nandsim_entry_size, nandsim_entry_count);
- } else if (nandsim_log_output == NANDSIM_OUTPUT_RAM) {
- sc->log_buff = malloc(log_size, M_NANDSIM, M_WAITOK | M_ZERO);
- if (!sc->log_buff)
- error = ENOMEM;
- }
-
- return (error);
-}
-
-void
-nandsim_log_close(struct nandsim_softc *sc)
-{
-
- if (nandsim_log_output == NANDSIM_OUTPUT_FILE) {
- memset(&string[str_index], 0, NANDSIM_ENTRY_SIZE - str_index);
- alq_write(sc->alq, (void *) string, ALQ_NOWAIT);
- str_index = 0;
- string[0] = '\0';
- alq_close(sc->alq);
- } else if (nandsim_log_output == NANDSIM_OUTPUT_RAM) {
- free(sc->log_buff, M_NANDSIM);
- sc->log_buff = NULL;
- }
-}
-
-void
-nandsim_log(struct nandsim_chip *chip, int level, const char *fmt, ...)
-{
- char hdr[TIME_STR_SIZE];
- char tmp[NANDSIM_ENTRY_SIZE];
- struct nandsim_softc *sc;
- struct timeval currtime;
- va_list ap;
- int hdr_len, len, rest;
-
- if (nandsim_log_output == NANDSIM_OUTPUT_NONE)
- return;
-
- if (chip == NULL)
- return;
-
- sc = chip->sc;
- if (!sc->alq && nandsim_log_output == NANDSIM_OUTPUT_FILE)
- return;
-
- if (level <= nandsim_log_level) {
- microtime(&currtime);
- hdr_len = sprintf(hdr, "%08jd.%08li [chip:%d, ctrl:%d]: ",
- (intmax_t)currtime.tv_sec, currtime.tv_usec,
- chip->chip_num, chip->ctrl_num);
-
- switch(nandsim_log_output) {
- case NANDSIM_OUTPUT_CONSOLE:
- printf("%s", hdr);
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- break;
- case NANDSIM_OUTPUT_RAM:
- va_start(ap, fmt);
- len = vsnprintf(tmp, NANDSIM_ENTRY_SIZE - 1, fmt, ap);
- tmp[NANDSIM_ENTRY_SIZE - 1] = 0;
- va_end(ap);
-
- rest = log_size - sc->log_idx - 1;
- if (rest >= hdr_len) {
- bcopy(hdr, &sc->log_buff[sc->log_idx],
- hdr_len);
- sc->log_idx += hdr_len;
- sc->log_buff[sc->log_idx] = 0;
- } else {
- bcopy(hdr, &sc->log_buff[sc->log_idx], rest);
- bcopy(&hdr[rest], sc->log_buff,
- hdr_len - rest);
- sc->log_idx = hdr_len - rest;
- sc->log_buff[sc->log_idx] = 0;
- }
-
- rest = log_size - sc->log_idx - 1;
- if (rest >= len) {
- bcopy(tmp, &sc->log_buff[sc->log_idx], len);
- sc->log_idx += len;
- sc->log_buff[sc->log_idx] = 0;
- } else {
- bcopy(tmp, &sc->log_buff[sc->log_idx], rest);
- bcopy(&tmp[rest], sc->log_buff, len - rest);
- sc->log_idx = len - rest;
- sc->log_buff[sc->log_idx] = 0;
- }
-
- break;
-
- case NANDSIM_OUTPUT_FILE:
- va_start(ap, fmt);
- len = vsnprintf(tmp, NANDSIM_ENTRY_SIZE - 1, fmt, ap);
- tmp[NANDSIM_ENTRY_SIZE - 1] = 0;
- va_end(ap);
-
- rest = NANDSIM_ENTRY_SIZE - str_index;
- if (rest >= hdr_len) {
- strcat(string, hdr);
- str_index += hdr_len;
- } else {
- strlcat(string, hdr, NANDSIM_ENTRY_SIZE + 1);
- alq_write(sc->alq, (void *) string,
- ALQ_NOWAIT);
- strcpy(string, &hdr[rest]);
- str_index = hdr_len - rest;
- }
- rest = NANDSIM_ENTRY_SIZE - str_index;
- if (rest >= len) {
- strcat(string, tmp);
- str_index += len;
- } else {
- strlcat(string, tmp, NANDSIM_ENTRY_SIZE + 1);
- alq_write(sc->alq, (void *) string,
- ALQ_NOWAIT);
- strcpy(string, &tmp[rest]);
- str_index = len - rest;
- }
- break;
- default:
- break;
- }
- }
-}
diff --git a/sys/dev/nand/nandsim_log.h b/sys/dev/nand/nandsim_log.h
deleted file mode 100644
index 5e5a055a4053..000000000000
--- a/sys/dev/nand/nandsim_log.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _NANDSIM_LOG_H
-#define _NANDSIM_LOG_H
-
-#include <dev/nand/nandsim_chip.h>
-
-#define NANDSIM_ENTRY_SIZE 128
-#define NANDSIM_ENTRY_COUNT 1024
-#define NANDSIM_RAM_LOG_SIZE 16384
-#define TIME_STR_SIZE 40
-
-#define NANDSIM_LOG_ERR 1
-#define NANDSIM_LOG_SM 5
-#define NANDSIM_LOG_EV 10
-#define NANDSIM_LOG_DATA 15
-
-extern int nandsim_log_level;
-extern int nandsim_log_output;
-
-int nandsim_log_init(struct nandsim_softc *, char *);
-void nandsim_log_close(struct nandsim_softc *);
-void nandsim_log(struct nandsim_chip *, int, const char *, ...);
-
-#endif /* _NANDSIM_LOG_H */
-
diff --git a/sys/dev/nand/nandsim_swap.c b/sys/dev/nand/nandsim_swap.c
deleted file mode 100644
index 78e14e9557bd..000000000000
--- a/sys/dev/nand/nandsim_swap.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/queue.h>
-#include <sys/fcntl.h>
-#include <sys/proc.h>
-#include <sys/namei.h>
-#include <sys/lock.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-
-#include <dev/nand/nandsim_chip.h>
-#include <dev/nand/nandsim_swap.h>
-
-static int init_block_state(struct chip_swap *);
-static void destroy_block_state(struct chip_swap *);
-
-static int create_buffers(struct chip_swap *);
-static void destroy_buffers(struct chip_swap *);
-
-static int swap_file_open(struct chip_swap *, const char *);
-static void swap_file_close(struct chip_swap *);
-static int swap_file_write(struct chip_swap *, struct block_state *);
-static int swap_file_read(struct chip_swap *, struct block_state *);
-
-#define CHIP_SWAP_CMODE 0600
-#define CHIP_SWAP_BLOCKSPACES 2
-
-static int
-init_block_state(struct chip_swap *swap)
-{
- struct block_state *blk_state;
- int i;
-
- if (swap == NULL)
- return (-1);
-
- blk_state = malloc(swap->nof_blks * sizeof(struct block_state),
- M_NANDSIM, M_WAITOK | M_ZERO);
-
- for (i = 0; i < swap->nof_blks; i++)
- blk_state[i].offset = 0xffffffff;
-
- swap->blk_state = blk_state;
-
- return (0);
-}
-
-static void
-destroy_block_state(struct chip_swap *swap)
-{
-
- if (swap == NULL)
- return;
-
- if (swap->blk_state != NULL)
- free(swap->blk_state, M_NANDSIM);
-}
-
-static int
-create_buffers(struct chip_swap *swap)
-{
- struct block_space *block_space;
- void *block;
- int i;
-
- for (i = 0; i < CHIP_SWAP_BLOCKSPACES; i++) {
- block_space = malloc(sizeof(*block_space), M_NANDSIM, M_WAITOK);
- block = malloc(swap->blk_size, M_NANDSIM, M_WAITOK);
- block_space->blk_ptr = block;
- SLIST_INSERT_HEAD(&swap->free_bs, block_space, free_link);
- nand_debug(NDBG_SIM,"created blk_space %p[%p]\n", block_space,
- block);
- }
-
- if (i == 0)
- return (-1);
-
- return (0);
-}
-
-static void
-destroy_buffers(struct chip_swap *swap)
-{
- struct block_space *blk_space;
-
- if (swap == NULL)
- return;
-
- blk_space = SLIST_FIRST(&swap->free_bs);
- while (blk_space) {
- SLIST_REMOVE_HEAD(&swap->free_bs, free_link);
- nand_debug(NDBG_SIM,"destroyed blk_space %p[%p]\n",
- blk_space, blk_space->blk_ptr);
- free(blk_space->blk_ptr, M_NANDSIM);
- free(blk_space, M_NANDSIM);
- blk_space = SLIST_FIRST(&swap->free_bs);
- }
-
- blk_space = STAILQ_FIRST(&swap->used_bs);
- while (blk_space) {
- STAILQ_REMOVE_HEAD(&swap->used_bs, used_link);
- nand_debug(NDBG_SIM,"destroyed blk_space %p[%p]\n",
- blk_space, blk_space->blk_ptr);
- free(blk_space->blk_ptr, M_NANDSIM);
- free(blk_space, M_NANDSIM);
- blk_space = STAILQ_FIRST(&swap->used_bs);
- }
-}
-
-static int
-swap_file_open(struct chip_swap *swap, const char *swap_file)
-{
- struct nameidata nd;
- int flags, error;
-
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, swap_file,
- curthread);
-
- flags = FWRITE | FREAD | O_NOFOLLOW | O_CREAT | O_TRUNC;
-
- error = vn_open(&nd, &flags, CHIP_SWAP_CMODE, NULL);
- if (error) {
- nand_debug(NDBG_SIM,"Cannot create swap file %s", swap_file);
- NDFREE(&nd, NDF_ONLY_PNBUF);
- return (error);
- }
-
- swap->swap_cred = crhold(curthread->td_ucred);
- NDFREE(&nd, NDF_ONLY_PNBUF);
-
- /* We just unlock so we hold a reference */
- VOP_UNLOCK(nd.ni_vp, 0);
-
- swap->swap_vp = nd.ni_vp;
-
- return (0);
-}
-
-static void
-swap_file_close(struct chip_swap *swap)
-{
-
- if (swap == NULL)
- return;
-
- if (swap->swap_vp == NULL)
- return;
-
- vn_close(swap->swap_vp, FWRITE, swap->swap_cred, curthread);
- crfree(swap->swap_cred);
-}
-
-static int
-swap_file_write(struct chip_swap *swap, struct block_state *blk_state)
-{
- struct block_space *blk_space;
- struct thread *td;
- struct mount *mp;
- struct vnode *vp;
- struct uio auio;
- struct iovec aiov;
-
- if (swap == NULL || blk_state == NULL)
- return (-1);
-
- blk_space = blk_state->blk_sp;
- if (blk_state->offset == -1) {
- blk_state->offset = swap->swap_offset;
- swap->swap_offset += swap->blk_size;
- }
-
- nand_debug(NDBG_SIM,"saving %p[%p] at %x\n",
- blk_space, blk_space->blk_ptr, blk_state->offset);
-
- bzero(&aiov, sizeof(aiov));
- bzero(&auio, sizeof(auio));
-
- aiov.iov_base = blk_space->blk_ptr;
- aiov.iov_len = swap->blk_size;
- td = curthread;
- vp = swap->swap_vp;
-
- auio.uio_iov = &aiov;
- auio.uio_offset = blk_state->offset;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_WRITE;
- auio.uio_iovcnt = 1;
- auio.uio_resid = swap->blk_size;
- auio.uio_td = td;
-
- vn_start_write(vp, &mp, V_WAIT);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- VOP_WRITE(vp, &auio, IO_UNIT, swap->swap_cred);
- VOP_UNLOCK(vp, 0);
- vn_finished_write(mp);
-
- return (0);
-}
-
-static int
-swap_file_read(struct chip_swap *swap, struct block_state *blk_state)
-{
- struct block_space *blk_space;
- struct thread *td;
- struct vnode *vp;
- struct uio auio;
- struct iovec aiov;
-
- if (swap == NULL || blk_state == NULL)
- return (-1);
-
- blk_space = blk_state->blk_sp;
-
- nand_debug(NDBG_SIM,"restore %p[%p] at %x\n",
- blk_space, blk_space->blk_ptr, blk_state->offset);
-
- bzero(&aiov, sizeof(aiov));
- bzero(&auio, sizeof(auio));
-
- aiov.iov_base = blk_space->blk_ptr;
- aiov.iov_len = swap->blk_size;
- td = curthread;
- vp = swap->swap_vp;
-
- auio.uio_iov = &aiov;
- auio.uio_offset = blk_state->offset;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_iovcnt = 1;
- auio.uio_resid = swap->blk_size;
- auio.uio_td = td;
-
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- VOP_READ(vp, &auio, 0, swap->swap_cred);
- VOP_UNLOCK(vp, 0);
-
- return (0);
-}
-
-struct chip_swap *
-nandsim_swap_init(const char *swap_file, uint32_t nof_blks, uint32_t blk_size)
-{
- struct chip_swap *swap;
- int err = 0;
-
- if ((swap_file == NULL) || (nof_blks == 0) || (blk_size == 0))
- return (NULL);
-
- swap = malloc(sizeof(*swap), M_NANDSIM, M_WAITOK | M_ZERO);
-
- SLIST_INIT(&swap->free_bs);
- STAILQ_INIT(&swap->used_bs);
- swap->blk_size = blk_size;
- swap->nof_blks = nof_blks;
-
- err = init_block_state(swap);
- if (err) {
- nandsim_swap_destroy(swap);
- return (NULL);
- }
-
- err = create_buffers(swap);
- if (err) {
- nandsim_swap_destroy(swap);
- return (NULL);
- }
-
- err = swap_file_open(swap, swap_file);
- if (err) {
- nandsim_swap_destroy(swap);
- return (NULL);
- }
-
- return (swap);
-}
-
-void
-nandsim_swap_destroy(struct chip_swap *swap)
-{
-
- if (swap == NULL)
- return;
-
- destroy_block_state(swap);
- destroy_buffers(swap);
- swap_file_close(swap);
- free(swap, M_NANDSIM);
-}
-
-struct block_space *
-get_bs(struct chip_swap *swap, uint32_t block, uint8_t writing)
-{
- struct block_state *blk_state, *old_blk_state = NULL;
- struct block_space *blk_space;
-
- if (swap == NULL || (block >= swap->nof_blks))
- return (NULL);
-
- blk_state = &swap->blk_state[block];
- nand_debug(NDBG_SIM,"blk_state %x\n", blk_state->status);
-
- if (blk_state->status & BLOCK_ALLOCATED) {
- blk_space = blk_state->blk_sp;
- } else {
- blk_space = SLIST_FIRST(&swap->free_bs);
- if (blk_space) {
- SLIST_REMOVE_HEAD(&swap->free_bs, free_link);
- STAILQ_INSERT_TAIL(&swap->used_bs, blk_space,
- used_link);
- } else {
- blk_space = STAILQ_FIRST(&swap->used_bs);
- old_blk_state = blk_space->blk_state;
- STAILQ_REMOVE_HEAD(&swap->used_bs, used_link);
- STAILQ_INSERT_TAIL(&swap->used_bs, blk_space,
- used_link);
- if (old_blk_state->status & BLOCK_DIRTY) {
- swap_file_write(swap, old_blk_state);
- old_blk_state->status &= ~BLOCK_DIRTY;
- old_blk_state->status |= BLOCK_SWAPPED;
- }
- }
- }
-
- if (blk_space == NULL)
- return (NULL);
-
- if (old_blk_state != NULL) {
- old_blk_state->status &= ~BLOCK_ALLOCATED;
- old_blk_state->blk_sp = NULL;
- }
-
- blk_state->blk_sp = blk_space;
- blk_space->blk_state = blk_state;
-
- if (!(blk_state->status & BLOCK_ALLOCATED)) {
- if (blk_state->status & BLOCK_SWAPPED)
- swap_file_read(swap, blk_state);
- else
- memset(blk_space->blk_ptr, 0xff, swap->blk_size);
- blk_state->status |= BLOCK_ALLOCATED;
- }
-
- if (writing)
- blk_state->status |= BLOCK_DIRTY;
-
- nand_debug(NDBG_SIM,"get_bs returned %p[%p] state %x\n", blk_space,
- blk_space->blk_ptr, blk_state->status);
-
- return (blk_space);
-}
diff --git a/sys/dev/nand/nandsim_swap.h b/sys/dev/nand/nandsim_swap.h
deleted file mode 100644
index c9eb0be63a9c..000000000000
--- a/sys/dev/nand/nandsim_swap.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _NANDSIM_SWAP_CHIP_H_
-#define _NANDSIM_SWAP_CHIP_H_
-
-struct block_space {
- SLIST_ENTRY(block_space) free_link;
- STAILQ_ENTRY(block_space) used_link;
- struct block_state *blk_state;
- uint8_t *blk_ptr;
-};
-
-#define BLOCK_ALLOCATED 0x1
-#define BLOCK_SWAPPED 0x2
-#define BLOCK_DIRTY 0x4
-
-struct block_state {
- struct block_space *blk_sp;
- uint32_t offset;
- uint8_t status;
-};
-
-struct chip_swap {
- struct block_state *blk_state;
- SLIST_HEAD(,block_space) free_bs;
- STAILQ_HEAD(,block_space) used_bs;
- struct ucred *swap_cred;
- struct vnode *swap_vp;
- uint32_t swap_offset;
- uint32_t blk_size;
- uint32_t nof_blks;
-};
-
-struct chip_swap *nandsim_swap_init(const char *, uint32_t, uint32_t);
-void nandsim_swap_destroy(struct chip_swap *);
-struct block_space *get_bs(struct chip_swap *, uint32_t, uint8_t);
-
-#endif /* _NANDSIM_SWAP_CHIP_H_ */
diff --git a/sys/dev/nand/nfc_fsl.c b/sys/dev/nand/nfc_fsl.c
deleted file mode 100644
index 992cfeb784fe..000000000000
--- a/sys/dev/nand/nfc_fsl.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2012 Juniper Networks, Inc.
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-/*
- * TODO :
- *
- * -- test support for small pages
- * -- support for reading ONFI parameters
- * -- support for cached and interleaving commands
- * -- proper setting of AL bits in FMR
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/kdb.h>
-
-#include <machine/bus.h>
-
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#include <powerpc/mpc85xx/lbc.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-
-#include "nfc_fsl.h"
-
-#include "nfc_if.h"
-
-#define LBC_READ(regname) lbc_read_reg(dev, (LBC85XX_ ## regname))
-#define LBC_WRITE(regname, val) lbc_write_reg(dev, (LBC85XX_ ## regname), val)
-
-enum addr_type {
- ADDR_NONE,
- ADDR_ID,
- ADDR_ROW,
- ADDR_ROWCOL
-};
-
-struct fsl_nfc_fcm {
- /* Read-only after initialization */
- uint32_t reg_fmr;
-
- /* To be preserved across "start_command" */
- u_int buf_ofs;
- u_int read_ptr;
- u_int status:1;
-
- /* Command state -- cleared by "start_command" */
- uint32_t fcm_startzero;
- uint32_t reg_fcr;
- uint32_t reg_fir;
- uint32_t reg_mdr;
- uint32_t reg_fbcr;
- uint32_t reg_fbar;
- uint32_t reg_fpar;
- u_int cmdnr;
- u_int opnr;
- u_int pg_ofs;
- enum addr_type addr_type;
- u_int addr_bytes;
- u_int row_addr;
- u_int column_addr;
- u_int data_fir:8;
- uint32_t fcm_endzero;
-};
-
-struct fsl_nand_softc {
- struct nand_softc nand_dev;
- device_t dev;
- struct resource *res;
- int rid; /* Resourceid */
- struct lbc_devinfo *dinfo;
- struct fsl_nfc_fcm fcm;
- uint8_t col_cycles;
- uint8_t row_cycles;
- uint16_t pgsz; /* Page size */
-};
-
-static int fsl_nand_attach(device_t dev);
-static int fsl_nand_probe(device_t dev);
-static int fsl_nand_detach(device_t dev);
-
-static int fsl_nfc_select_cs(device_t dev, uint8_t cs);
-static int fsl_nfc_read_rnb(device_t dev);
-static int fsl_nfc_send_command(device_t dev, uint8_t command);
-static int fsl_nfc_send_address(device_t dev, uint8_t address);
-static uint8_t fsl_nfc_read_byte(device_t dev);
-static int fsl_nfc_start_command(device_t dev);
-static void fsl_nfc_read_buf(device_t dev, void *buf, uint32_t len);
-static void fsl_nfc_write_buf(device_t dev, void *buf, uint32_t len);
-
-static device_method_t fsl_nand_methods[] = {
- DEVMETHOD(device_probe, fsl_nand_probe),
- DEVMETHOD(device_attach, fsl_nand_attach),
- DEVMETHOD(device_detach, fsl_nand_detach),
-
- DEVMETHOD(nfc_select_cs, fsl_nfc_select_cs),
- DEVMETHOD(nfc_read_rnb, fsl_nfc_read_rnb),
- DEVMETHOD(nfc_start_command, fsl_nfc_start_command),
- DEVMETHOD(nfc_send_command, fsl_nfc_send_command),
- DEVMETHOD(nfc_send_address, fsl_nfc_send_address),
- DEVMETHOD(nfc_read_byte, fsl_nfc_read_byte),
- DEVMETHOD(nfc_read_buf, fsl_nfc_read_buf),
- DEVMETHOD(nfc_write_buf, fsl_nfc_write_buf),
- { 0, 0 },
-};
-
-static driver_t fsl_nand_driver = {
- "nand",
- fsl_nand_methods,
- sizeof(struct fsl_nand_softc),
-};
-
-static devclass_t fsl_nand_devclass;
-
-DRIVER_MODULE(fsl_nand, lbc, fsl_nand_driver, fsl_nand_devclass,
- 0, 0);
-
-static int fsl_nand_build_address(device_t dev, uint32_t page, uint32_t column);
-static int fsl_nand_chip_preprobe(device_t dev, struct nand_id *id);
-
-#ifdef NAND_DEBUG_TIMING
-static device_t fcm_devs[8];
-#endif
-
-#define CMD_SHIFT(cmd_num) (24 - ((cmd_num) * 8))
-#define OP_SHIFT(op_num) (28 - ((op_num) * 4))
-
-#define FSL_LARGE_PAGE_SIZE (2112)
-#define FSL_SMALL_PAGE_SIZE (528)
-
-static void
-fsl_nand_init_regs(struct fsl_nand_softc *sc)
-{
- uint32_t or_v, br_v;
- device_t dev;
-
- dev = sc->dev;
-
- sc->fcm.reg_fmr = (15 << FMR_CWTO_SHIFT);
-
- /*
- * Setup 4 row cycles and hope that chip ignores superfluous address
- * bytes.
- */
- sc->fcm.reg_fmr |= (2 << FMR_AL_SHIFT);
-
- /* Reprogram BR(x) */
- br_v = lbc_read_reg(dev, LBC85XX_BR(sc->dinfo->di_bank));
- br_v &= 0xffff8000;
- br_v |= 1 << 11; /* 8-bit port size */
- br_v |= 0 << 9; /* No ECC checking and generation */
- br_v |= 1 << 5; /* FCM machine */
- br_v |= 1; /* Valid */
- lbc_write_reg(dev, LBC85XX_BR(sc->dinfo->di_bank), br_v);
-
- /* Reprogram OR(x) */
- or_v = lbc_read_reg(dev, LBC85XX_OR(sc->dinfo->di_bank));
- or_v &= 0xfffffc00;
- or_v |= 0x03AE; /* Default POR timing */
- lbc_write_reg(dev, LBC85XX_OR(sc->dinfo->di_bank), or_v);
-
- if (or_v & OR_FCM_PAGESIZE) {
- sc->pgsz = FSL_LARGE_PAGE_SIZE;
- sc->col_cycles = 2;
- nand_debug(NDBG_DRV, "%s: large page NAND device at #%d",
- device_get_nameunit(dev), sc->dinfo->di_bank);
- } else {
- sc->pgsz = FSL_SMALL_PAGE_SIZE;
- sc->col_cycles = 1;
- nand_debug(NDBG_DRV, "%s: small page NAND device at #%d",
- device_get_nameunit(dev), sc->dinfo->di_bank);
- }
-}
-
-static int
-fsl_nand_probe(device_t dev)
-{
-
- if (!ofw_bus_is_compatible(dev, "fsl,elbc-fcm-nand"))
- return (ENXIO);
-
- device_set_desc(dev, "Freescale localbus FCM Controller");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-fsl_nand_attach(device_t dev)
-{
- struct fsl_nand_softc *sc;
- struct nand_id id;
- struct nand_params *param;
- uint32_t num_pages;
-
- sc = device_get_softc(dev);
- sc->dev = dev;
- sc->dinfo = device_get_ivars(dev);
-
- sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
- RF_ACTIVE);
- if (sc->res == NULL) {
- device_printf(dev, "could not allocate resources!\n");
- return (ENXIO);
- }
-
- bzero(&sc->fcm, sizeof(sc->fcm));
-
- /* Init register and check if HW ECC turned on */
- fsl_nand_init_regs(sc);
-
- /* Chip is probed, so determine number of row address cycles */
- fsl_nand_chip_preprobe(dev, &id);
- param = nand_get_params(&id);
- if (param != NULL) {
- num_pages = (param->chip_size << 20) / param->page_size;
- while(num_pages) {
- sc->row_cycles++;
- num_pages >>= 8;
- }
-
- sc->fcm.reg_fmr &= ~(FMR_AL);
- sc->fcm.reg_fmr |= (sc->row_cycles - 2) << FMR_AL_SHIFT;
- }
-
- nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL);
-
-#ifdef NAND_DEBUG_TIMING
- fcm_devs[sc->dinfo->di_bank] = dev;
-#endif
-
- return (nandbus_create(dev));
-}
-
-static int
-fsl_nand_detach(device_t dev)
-{
- struct fsl_nand_softc *sc;
-
- sc = device_get_softc(dev);
-
- if (sc->res != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res);
-
- return (0);
-}
-
-static int
-fsl_nfc_select_cs(device_t dev, uint8_t cs)
-{
-
- // device_printf(dev, "%s(cs=%u)\n", __func__, cs);
- return ((cs > 0) ? EINVAL : 0);
-}
-
-static int
-fsl_nfc_read_rnb(device_t dev)
-{
-
- // device_printf(dev, "%s()\n", __func__);
- return (0);
-}
-
-static int
-fsl_nfc_send_command(device_t dev, uint8_t command)
-{
- struct fsl_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- uint8_t fir_op;
-
- // device_printf(dev, "%s(command=%u)\n", __func__, command);
-
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- if (command == NAND_CMD_PROG_END) {
- fcm->reg_fir |= (FIR_OP_WB << OP_SHIFT(fcm->opnr));
- fcm->opnr++;
- }
- fcm->reg_fcr |= command << CMD_SHIFT(fcm->cmdnr);
- fir_op = (fcm->cmdnr == 0) ? FIR_OP_CW0 : FIR_OP_CM(fcm->cmdnr);
- fcm->cmdnr++;
-
- fcm->reg_fir |= (fir_op << OP_SHIFT(fcm->opnr));
- fcm->opnr++;
-
- switch (command) {
- case NAND_CMD_READ_ID:
- fcm->data_fir = FIR_OP_RBW;
- fcm->addr_type = ADDR_ID;
- break;
- case NAND_CMD_SMALLOOB:
- fcm->pg_ofs += 256;
- /*FALLTHROUGH*/
- case NAND_CMD_SMALLB:
- fcm->pg_ofs += 256;
- /*FALLTHROUGH*/
- case NAND_CMD_READ: /* NAND_CMD_SMALLA */
- fcm->data_fir = FIR_OP_RBW;
- fcm->addr_type = ADDR_ROWCOL;
- break;
- case NAND_CMD_STATUS:
- fcm->data_fir = FIR_OP_RS;
- fcm->status = 1;
- break;
- case NAND_CMD_ERASE:
- fcm->addr_type = ADDR_ROW;
- break;
- case NAND_CMD_PROG:
- fcm->addr_type = ADDR_ROWCOL;
- break;
- }
- return (0);
-}
-
-static int
-fsl_nfc_send_address(device_t dev, uint8_t addr)
-{
- struct fsl_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- uint32_t addr_bits;
-
- // device_printf(dev, "%s(address=%u)\n", __func__, addr);
-
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- KASSERT(fcm->addr_type != ADDR_NONE,
- ("controller doesn't expect address cycle"));
-
- addr_bits = addr;
-
- if (fcm->addr_type == ADDR_ID) {
- fcm->reg_fir |= (FIR_OP_UA << OP_SHIFT(fcm->opnr));
- fcm->opnr++;
-
- fcm->reg_fbcr = 5;
- fcm->reg_fbar = 0;
- fcm->reg_fpar = 0;
- fcm->reg_mdr = addr_bits;
- fcm->buf_ofs = 0;
- fcm->read_ptr = 0;
- return (0);
- }
-
- if (fcm->addr_type == ADDR_ROW) {
- addr_bits <<= fcm->addr_bytes * 8;
- fcm->row_addr |= addr_bits;
- fcm->addr_bytes++;
- if (fcm->addr_bytes < sc->row_cycles)
- return (0);
- } else {
- if (fcm->addr_bytes < sc->col_cycles) {
- addr_bits <<= fcm->addr_bytes * 8;
- fcm->column_addr |= addr_bits;
- } else {
- addr_bits <<= (fcm->addr_bytes - sc->col_cycles) * 8;
- fcm->row_addr |= addr_bits;
- }
- fcm->addr_bytes++;
- if (fcm->addr_bytes < (sc->row_cycles + sc->col_cycles))
- return (0);
- }
-
- return (fsl_nand_build_address(dev, fcm->row_addr, fcm->column_addr));
-}
-
-static int
-fsl_nand_build_address(device_t dev, uint32_t row, uint32_t column)
-{
- struct fsl_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- uint32_t byte_count = 0;
- uint32_t block_address = 0;
- uint32_t page_address = 0;
-
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- fcm->read_ptr = 0;
- fcm->buf_ofs = 0;
-
- if (fcm->addr_type == ADDR_ROWCOL) {
- fcm->reg_fir |= (FIR_OP_CA << OP_SHIFT(fcm->opnr));
- fcm->opnr++;
-
- column += fcm->pg_ofs;
- fcm->pg_ofs = 0;
-
- page_address |= column;
-
- if (column != 0) {
- byte_count = sc->pgsz - column;
- fcm->read_ptr = column;
- }
- }
-
- fcm->reg_fir |= (FIR_OP_PA << OP_SHIFT(fcm->opnr));
- fcm->opnr++;
-
- if (sc->pgsz == FSL_LARGE_PAGE_SIZE) {
- block_address = row >> 6;
- page_address |= ((row << FPAR_LP_PI_SHIFT) & FPAR_LP_PI);
- fcm->buf_ofs = (row & 1) * 4096;
- } else {
- block_address = row >> 5;
- page_address |= ((row << FPAR_SP_PI_SHIFT) & FPAR_SP_PI);
- fcm->buf_ofs = (row & 7) * 1024;
- }
-
- fcm->reg_fbcr = byte_count;
- fcm->reg_fbar = block_address;
- fcm->reg_fpar = page_address;
- return (0);
-}
-
-static int
-fsl_nfc_start_command(device_t dev)
-{
- struct fsl_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- uint32_t fmr, ltesr_v;
- int error, timeout;
-
- // device_printf(dev, "%s()\n", __func__);
-
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- fmr = fcm->reg_fmr | FMR_OP;
-
- if (fcm->data_fir)
- fcm->reg_fir |= (fcm->data_fir << OP_SHIFT(fcm->opnr));
-
- LBC_WRITE(FIR, fcm->reg_fir);
- LBC_WRITE(FCR, fcm->reg_fcr);
-
- LBC_WRITE(FMR, fmr);
-
- LBC_WRITE(FBCR, fcm->reg_fbcr);
- LBC_WRITE(FBAR, fcm->reg_fbar);
- LBC_WRITE(FPAR, fcm->reg_fpar);
-
- if (fcm->addr_type == ADDR_ID)
- LBC_WRITE(MDR, fcm->reg_mdr);
-
- nand_debug(NDBG_DRV, "BEFORE:\nFMR=%#x, FIR=%#x, FCR=%#x", fmr,
- fcm->reg_fir, fcm->reg_fcr);
- nand_debug(NDBG_DRV, "MDR=%#x, FBAR=%#x, FPAR=%#x, FBCR=%#x",
- LBC_READ(MDR), fcm->reg_fbar, fcm->reg_fpar, fcm->reg_fbcr);
-
- LBC_WRITE(LSOR, sc->dinfo->di_bank);
-
- timeout = (cold) ? FSL_FCM_WAIT_TIMEOUT : ~0;
- error = 0;
- ltesr_v = LBC_READ(LTESR);
- while (!error && (ltesr_v & LTESR_CC) == 0) {
- if (cold) {
- DELAY(1000);
- timeout--;
- if (timeout < 0)
- error = EWOULDBLOCK;
- } else
- error = tsleep(device_get_parent(sc->dev), PRIBIO,
- "nfcfsl", hz);
- ltesr_v = LBC_READ(LTESR);
- }
- if (error)
- nand_debug(NDBG_DRV, "Command complete wait timeout\n");
-
- nand_debug(NDBG_DRV, "AFTER:\nLTESR=%#x, LTEDR=%#x, LTEIR=%#x,"
- " LTEATR=%#x, LTEAR=%#x, LTECCR=%#x", ltesr_v,
- LBC_READ(LTEDR), LBC_READ(LTEIR), LBC_READ(LTEATR),
- LBC_READ(LTEAR), LBC_READ(LTECCR));
-
- bzero(&fcm->fcm_startzero,
- __rangeof(struct fsl_nfc_fcm, fcm_startzero, fcm_endzero));
-
- if (fcm->status)
- sc->fcm.reg_mdr = LBC_READ(MDR);
-
- /* Even if timeout occurred, we should perform steps below */
- LBC_WRITE(LTESR, ltesr_v);
- LBC_WRITE(LTEATR, 0);
-
- return (error);
-}
-
-static uint8_t
-fsl_nfc_read_byte(device_t dev)
-{
- struct fsl_nand_softc *sc = device_get_softc(dev);
- uint32_t offset;
-
- // device_printf(dev, "%s()\n", __func__);
-
- /*
- * LBC controller allows us to read status into a MDR instead of FCM
- * buffer. If last operation requested before read_byte() was STATUS,
- * then return MDR instead of reading a single byte from a buffer.
- */
- if (sc->fcm.status) {
- sc->fcm.status = 0;
- return (sc->fcm.reg_mdr);
- }
-
- KASSERT(sc->fcm.read_ptr < sc->pgsz,
- ("Attempt to read beyond buffer %x %x", sc->fcm.read_ptr,
- sc->pgsz));
-
- offset = sc->fcm.buf_ofs + sc->fcm.read_ptr;
- sc->fcm.read_ptr++;
- return (bus_read_1(sc->res, offset));
-}
-
-static void
-fsl_nfc_read_buf(device_t dev, void *buf, uint32_t len)
-{
- struct fsl_nand_softc *sc = device_get_softc(dev);
- uint32_t offset;
- int bytesleft = 0;
-
- // device_printf(dev, "%s(buf=%p, len=%u)\n", __func__, buf, len);
-
- nand_debug(NDBG_DRV, "REQUEST OF 0x%0x B (BIB=0x%0x, NTR=0x%0x)",
- len, sc->pgsz, sc->fcm.read_ptr);
-
- bytesleft = MIN((unsigned int)len, sc->pgsz - sc->fcm.read_ptr);
-
- offset = sc->fcm.buf_ofs + sc->fcm.read_ptr;
- bus_read_region_1(sc->res, offset, buf, bytesleft);
- sc->fcm.read_ptr += bytesleft;
-}
-
-static void
-fsl_nfc_write_buf(device_t dev, void *buf, uint32_t len)
-{
- struct fsl_nand_softc *sc = device_get_softc(dev);
- uint32_t offset;
- int bytesleft = 0;
-
- // device_printf(dev, "%s(buf=%p, len=%u)\n", __func__, buf, len);
-
- KASSERT(len <= sc->pgsz - sc->fcm.read_ptr,
- ("Attempt to write beyond buffer"));
-
- bytesleft = MIN((unsigned int)len, sc->pgsz - sc->fcm.read_ptr);
-
- nand_debug(NDBG_DRV, "REQUEST TO WRITE 0x%0x (BIB=0x%0x, NTR=0x%0x)",
- bytesleft, sc->pgsz, sc->fcm.read_ptr);
-
- offset = sc->fcm.buf_ofs + sc->fcm.read_ptr;
- bus_write_region_1(sc->res, offset, buf, bytesleft);
- sc->fcm.read_ptr += bytesleft;
-}
-
-static int
-fsl_nand_chip_preprobe(device_t dev, struct nand_id *id)
-{
-
- if (fsl_nfc_send_command(dev, NAND_CMD_RESET) != 0)
- return (ENXIO);
-
- if (fsl_nfc_start_command(dev) != 0)
- return (ENXIO);
-
- DELAY(1000);
-
- if (fsl_nfc_send_command(dev, NAND_CMD_READ_ID))
- return (ENXIO);
-
- if (fsl_nfc_send_address(dev, 0))
- return (ENXIO);
-
- if (fsl_nfc_start_command(dev) != 0)
- return (ENXIO);
-
- DELAY(25);
-
- id->man_id = fsl_nfc_read_byte(dev);
- id->dev_id = fsl_nfc_read_byte(dev);
-
- nand_debug(NDBG_DRV, "manufacturer id: %x chip id: %x",
- id->man_id, id->dev_id);
-
- return (0);
-}
-
-#ifdef NAND_DEBUG_TIMING
-
-static SYSCTL_NODE(_debug, OID_AUTO, fcm, CTLFLAG_RD, 0, "FCM timing");
-
-static u_int csct = 1; /* 22: Chip select to command time (trlx). */
-SYSCTL_UINT(_debug_fcm, OID_AUTO, csct, CTLFLAG_RW, &csct, 1,
- "Chip select to command time: determines how far in advance -LCSn is "
- "asserted prior to any bus activity during a NAND Flash access handled "
- "by the FCM. This helps meet chip-select setup times for slow memories.");
-
-static u_int cst = 1; /* 23: Command setup time (trlx). */
-SYSCTL_UINT(_debug_fcm, OID_AUTO, cst, CTLFLAG_RW, &cst, 1,
- "Command setup time: determines the delay of -LFWE assertion relative to "
- "the command, address, or data change when the external memory access "
- "is handled by the FCM.");
-
-static u_int cht = 1; /* 24: Command hold time (trlx). */
-SYSCTL_UINT(_debug_fcm, OID_AUTO, cht, CTLFLAG_RW, &cht, 1,
- "Command hold time: determines the -LFWE negation prior to the command, "
- "address, or data change when the external memory access is handled by "
- "the FCM.");
-
-static u_int scy = 2; /* 25-27: Cycle length in bus clocks */
-SYSCTL_UINT(_debug_fcm, OID_AUTO, scy, CTLFLAG_RW, &scy, 2,
- "Cycle length in bus clocks: see RM");
-
-static u_int rst = 1; /* 28: Read setup time (trlx). */
-SYSCTL_UINT(_debug_fcm, OID_AUTO, rst, CTLFLAG_RW, &rst, 1,
- "Read setup time: determines the delay of -LFRE assertion relative to "
- "sampling of read data when the external memory access is handled by "
- "the FCM.");
-
-static u_int trlx = 1; /* 29: Timing relaxed. */
-SYSCTL_UINT(_debug_fcm, OID_AUTO, trlx, CTLFLAG_RW, &trlx, 1,
- "Timing relaxed: modifies the settings of timing parameters for slow "
- "memories. See RM");
-
-static u_int ehtr = 1; /* 30: Extended hold time on read accesses. */
-SYSCTL_UINT(_debug_fcm, OID_AUTO, ehtr, CTLFLAG_RW, &ehtr, 1,
- "Extended hold time on read accesses: indicates with TRLX how many "
- "cycles are inserted between a read access from the current bank and "
- "the next access.");
-
-static u_int
-fsl_nand_get_timing(void)
-{
- u_int timing;
-
- timing = ((csct & 1) << 9) | ((cst & 1) << 8) | ((cht & 1) << 7) |
- ((scy & 7) << 4) | ((rst & 1) << 3) | ((trlx & 1) << 2) |
- ((ehtr & 1) << 1);
-
- printf("nfc_fsl: timing = %u\n", timing);
- return (timing);
-}
-
-static int
-fsl_sysctl_program(SYSCTL_HANDLER_ARGS)
-{
- struct fsl_nand_softc *sc;
- int error, i;
- device_t dev;
- uint32_t or_v;
-
- error = sysctl_wire_old_buffer(req, sizeof(int));
- if (error == 0) {
- i = 0;
- error = sysctl_handle_int(oidp, &i, 0, req);
- }
- if (error != 0 || req->newptr == NULL)
- return (error);
-
- for (i = 0; i < 8; i++) {
- dev = fcm_devs[i];
- if (dev == NULL)
- continue;
- sc = device_get_softc(dev);
-
- /* Reprogram OR(x) */
- or_v = lbc_read_reg(dev, LBC85XX_OR(sc->dinfo->di_bank));
- or_v &= 0xfffffc00;
- or_v |= fsl_nand_get_timing();
- lbc_write_reg(dev, LBC85XX_OR(sc->dinfo->di_bank), or_v);
- }
- return (0);
-}
-
-SYSCTL_PROC(_debug_fcm, OID_AUTO, program, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
- fsl_sysctl_program, "I", "write to program FCM with current values");
-
-#endif /* NAND_DEBUG_TIMING */
diff --git a/sys/dev/nand/nfc_fsl.h b/sys/dev/nand/nfc_fsl.h
deleted file mode 100644
index 5410da558171..000000000000
--- a/sys/dev/nand/nfc_fsl.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2012 Juniper Networks, Inc.
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _NAND_NFC_FSL_H_
-#define _NAND_NFC_FSL_H_
-
-/* LBC BR/OR Registers layout definitions */
-#define BR_V 0x00000001
-#define BR_V_SHIFT 0
-#define BR_MSEL 0x000000E0
-#define BR_MSEL_SHIFT 5
-#define BR_DECC_CHECK_MODE 0x00000600
-#define BR_DECC_CHECK_GEN 0x00000400
-
-#define OR_FCM_PAGESIZE 0x00000400
-
-/* Options definitions */
-#define NAND_OPT_ECC_MODE_HW 1
-#define NAND_OPT_ECC_MODE_SOFT (1 << 1)
-
-/* FMR - Flash Mode Register */
-#define FMR_CWTO 0xF000
-#define FMR_CWTO_SHIFT 12
-#define FMR_BOOT 0x0800
-#define FMR_ECCM 0x0100
-#define FMR_AL 0x0030
-#define FMR_AL_SHIFT 4
-#define FMR_OP 0x0003
-#define FMR_OP_SHIFT 0
-
-#define FIR_OP_NOP 0x0 /* No operation and end of sequence */
-#define FIR_OP_CA 0x1 /* Issue current column address */
-#define FIR_OP_PA 0x2 /* Issue current block+page address */
-#define FIR_OP_UA 0x3 /* Issue user defined address */
-#define FIR_OP_CM(x) (4 + (x)) /* Issue command from FCR[CMD(x)] */
-#define FIR_OP_WB 0x8 /* Write FBCR bytes from FCM buffer */
-#define FIR_OP_WS 0x9 /* Write 1 or 2 bytes from MDR[AS] */
-#define FIR_OP_RB 0xA /* Read FBCR bytes to FCM buffer */
-#define FIR_OP_RS 0xB /* Read 1 or 2 bytes to MDR[AS] */
-#define FIR_OP_CW0 0xC /* Wait then issue FCR[CMD0] */
-#define FIR_OP_CW1 0xD /* Wait then issue FCR[CMD1] */
-#define FIR_OP_RBW 0xE /* Wait then read FBCR bytes */
-#define FIR_OP_RSW 0xF /* Wait then read 1 or 2 bytes */
-
-/* LTESR - Transfer Error Status Register */
-#define LTESR_BM 0x80000000
-#define LTESR_FCT 0x40000000
-#define LTESR_PAR 0x20000000
-#define LTESR_WP 0x04000000
-#define LTESR_ATMW 0x00800000
-#define LTESR_ATMR 0x00400000
-#define LTESR_CS 0x00080000
-#define LTESR_CC 0x00000001
-
-#define LTESR_NAND_MASK (LTESR_FCT | LTESR_CC | LTESR_CS)
-
-/* FPAR - Flash Page Address Register */
-#define FPAR_SP_PI 0x00007C00
-#define FPAR_SP_PI_SHIFT 10
-#define FPAR_SP_MS 0x00000200
-#define FPAR_SP_CI 0x000001FF
-#define FPAR_SP_CI_SHIFT 0
-#define FPAR_LP_PI 0x0003F000
-#define FPAR_LP_PI_SHIFT 12
-#define FPAR_LP_MS 0x00000800
-#define FPAR_LP_CI 0x000007FF
-#define FPAR_LP_CI_SHIFT 0
-
-#define FSL_FCM_WAIT_TIMEOUT 10
-
-#endif /* _NAND_NFC_FSL_H_ */
diff --git a/sys/dev/nand/nfc_if.m b/sys/dev/nand/nfc_if.m
deleted file mode 100644
index a4e1099220ac..000000000000
--- a/sys/dev/nand/nfc_if.m
+++ /dev/null
@@ -1,165 +0,0 @@
-#-
-# Copyright (C) 2009-2012 Semihalf
-# All rights reserved.
-#
-# 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
-#
-# $FreeBSD$
-
-# NAND controller interface description
-#
-
-#include <sys/bus.h>
-#include <dev/nand/nand.h>
-
-INTERFACE nfc;
-
-CODE {
- static int nfc_default_method(device_t dev)
- {
- return (0);
- }
-
- static int nfc_softecc_get(device_t dev, void *buf, int pagesize,
- void *ecc, int *needwrite)
- {
- *needwrite = 1;
- return (nand_softecc_get(dev, buf, pagesize, ecc));
- }
-
- static int nfc_softecc_correct(device_t dev, void *buf, int pagesize,
- void *readecc, void *calcecc)
- {
- return (nand_softecc_correct(dev, buf, pagesize, readecc,
- calcecc));
- }
-};
-
-# Send command to a NAND chip
-#
-# Return values:
-# 0: Success
-#
-METHOD int send_command {
- device_t dev;
- uint8_t command;
-};
-
-# Send address to a NAND chip
-#
-# Return values:
-# 0: Success
-#
-METHOD int send_address {
- device_t dev;
- uint8_t address;
-};
-
-# Read byte
-#
-# Return values:
-# byte read
-#
-METHOD uint8_t read_byte {
- device_t dev;
-};
-
-# Write byte
-#
-METHOD void write_byte {
- device_t dev;
- uint8_t byte;
-};
-
-# Read word
-#
-# Return values:
-# word read
-#
-METHOD uint16_t read_word {
- device_t dev;
-};
-
-# Write word
-#
-METHOD void write_word {
- device_t dev;
- uint16_t word;
-};
-
-# Read buf
-#
-METHOD void read_buf {
- device_t dev;
- void *buf;
- uint32_t len;
-};
-
-# Write buf
-#
-METHOD void write_buf {
- device_t dev;
- void *buf;
- uint32_t len;
-};
-
-# Select CS
-#
-METHOD int select_cs {
- device_t dev;
- uint8_t cs;
-};
-
-# Read ready/busy signal
-#
-METHOD int read_rnb {
- device_t dev;
-};
-
-# Start command
-#
-# Return values:
-# 0: Success
-#
-METHOD int start_command {
- device_t dev;
-} DEFAULT nfc_default_method;
-
-# Generate ECC or get it from H/W
-#
-METHOD int get_ecc {
- device_t dev;
- void *buf;
- int pagesize;
- void *ecc;
- int *needwrite;
-} DEFAULT nfc_softecc_get;
-
-# Correct ECC
-#
-METHOD int correct_ecc {
- device_t dev;
- void *buf;
- int pagesize;
- void *readecc;
- void *calcecc;
-} DEFAULT nfc_softecc_correct;
diff --git a/sys/dev/nand/nfc_mv.c b/sys/dev/nand/nfc_mv.c
deleted file mode 100644
index 0d78d34d9912..000000000000
--- a/sys/dev/nand/nfc_mv.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 2009-2012 Semihalf
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-/* Integrated NAND controller driver */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/time.h>
-
-#include <machine/bus.h>
-#include <machine/fdt.h>
-#include <arm/mv/mvvar.h>
-#include <arm/mv/mvwin.h>
-
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-#include "nfc_if.h"
-
-#define MV_NAND_DATA (0x00)
-#define MV_NAND_COMMAND (0x01)
-#define MV_NAND_ADDRESS (0x02)
-
-struct mv_nand_softc {
- struct nand_softc nand_dev;
- bus_space_handle_t sc_handle;
- bus_space_tag_t sc_tag;
- struct resource *res;
- int rid;
-};
-
-static int mv_nand_attach(device_t);
-static int mv_nand_probe(device_t);
-static int mv_nand_send_command(device_t, uint8_t);
-static int mv_nand_send_address(device_t, uint8_t);
-static uint8_t mv_nand_read_byte(device_t);
-static void mv_nand_read_buf(device_t, void *, uint32_t);
-static void mv_nand_write_buf(device_t, void *, uint32_t);
-static int mv_nand_select_cs(device_t, uint8_t);
-static int mv_nand_read_rnb(device_t);
-
-static device_method_t mv_nand_methods[] = {
- DEVMETHOD(device_probe, mv_nand_probe),
- DEVMETHOD(device_attach, mv_nand_attach),
-
- DEVMETHOD(nfc_send_command, mv_nand_send_command),
- DEVMETHOD(nfc_send_address, mv_nand_send_address),
- DEVMETHOD(nfc_read_byte, mv_nand_read_byte),
- DEVMETHOD(nfc_read_buf, mv_nand_read_buf),
- DEVMETHOD(nfc_write_buf, mv_nand_write_buf),
- DEVMETHOD(nfc_select_cs, mv_nand_select_cs),
- DEVMETHOD(nfc_read_rnb, mv_nand_read_rnb),
-
- { 0, 0 },
-};
-
-static driver_t mv_nand_driver = {
- "nand",
- mv_nand_methods,
- sizeof(struct mv_nand_softc),
-};
-
-static devclass_t mv_nand_devclass;
-DRIVER_MODULE(mv_nand, localbus, mv_nand_driver, mv_nand_devclass, 0, 0);
-
-static int
-mv_nand_probe(device_t dev)
-{
-
- if (!ofw_bus_is_compatible(dev, "mrvl,nfc"))
- return (ENXIO);
-
- device_set_desc(dev, "Marvell NAND controller");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-mv_nand_attach(device_t dev)
-{
- struct mv_nand_softc *sc;
- int err;
-
- sc = device_get_softc(dev);
- sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
- RF_ACTIVE);
- if (sc->res == NULL) {
- device_printf(dev, "could not allocate resources!\n");
- return (ENXIO);
- }
-
- sc->sc_tag = rman_get_bustag(sc->res);
- sc->sc_handle = rman_get_bushandle(sc->res);
-
- nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL);
-
- err = nandbus_create(dev);
-
- return (err);
-}
-
-static int
-mv_nand_send_command(device_t dev, uint8_t command)
-{
- struct mv_nand_softc *sc;
-
- nand_debug(NDBG_DRV,"mv_nand: send command %x", command);
-
- sc = device_get_softc(dev);
- bus_space_write_1(sc->sc_tag, sc->sc_handle, MV_NAND_COMMAND, command);
- return (0);
-}
-
-static int
-mv_nand_send_address(device_t dev, uint8_t addr)
-{
- struct mv_nand_softc *sc;
-
- nand_debug(NDBG_DRV,"mv_nand: send address %x", addr);
-
- sc = device_get_softc(dev);
- bus_space_write_1(sc->sc_tag, sc->sc_handle, MV_NAND_ADDRESS, addr);
- return (0);
-}
-
-static uint8_t
-mv_nand_read_byte(device_t dev)
-{
- struct mv_nand_softc *sc;
- uint8_t data;
-
- sc = device_get_softc(dev);
- data = bus_space_read_1(sc->sc_tag, sc->sc_handle, MV_NAND_DATA);
-
- nand_debug(NDBG_DRV,"mv_nand: read %x", data);
-
- return (data);
-}
-
-static void
-mv_nand_read_buf(device_t dev, void* buf, uint32_t len)
-{
- struct mv_nand_softc *sc;
- int i;
- uint8_t *b = (uint8_t*)buf;
-
- sc = device_get_softc(dev);
-
- for (i = 0; i < len; i++) {
- b[i] = bus_space_read_1(sc->sc_tag, sc->sc_handle,
- MV_NAND_DATA);
-#ifdef NAND_DEBUG
- if (!(i % 16))
- printf("%s", i == 0 ? "mv_nand:\n" : "\n");
- printf(" %x", b[i]);
- if (i == len - 1)
- printf("\n");
-#endif
- }
-}
-
-static void
-mv_nand_write_buf(device_t dev, void* buf, uint32_t len)
-{
- struct mv_nand_softc *sc;
- int i;
- uint8_t *b = (uint8_t*)buf;
-
- sc = device_get_softc(dev);
-
- for (i = 0; i < len; i++) {
-#ifdef NAND_DEBUG
- if (!(i % 16))
- printf("%s", i == 0 ? "mv_nand:\n" : "\n");
- printf(" %x", b[i]);
- if (i == len - 1)
- printf("\n");
-#endif
- bus_space_write_1(sc->sc_tag, sc->sc_handle, MV_NAND_DATA,
- b[i]);
- }
-}
-
-static int
-mv_nand_select_cs(device_t dev, uint8_t cs)
-{
-
- if (cs > 0)
- return (ENODEV);
-
- return (0);
-}
-
-static int
-mv_nand_read_rnb(device_t dev)
-{
-
- /* no-op */
- return (0); /* ready */
-}
diff --git a/sys/dev/nand/nfc_rb.c b/sys/dev/nand/nfc_rb.c
deleted file mode 100644
index 1102b3abb9c4..000000000000
--- a/sys/dev/nand/nfc_rb.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*-
- * Copyright (C) 2015 Justin Hibbits
- * All rights reserved.
- *
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-/* RouterBoard 600/800 NAND controller driver. */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <sys/slicer.h>
-
-#include <geom/geom_disk.h>
-
-#include <machine/bus.h>
-
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-
-#include <powerpc/mpc85xx/mpc85xx.h>
-
-#include "nfc_if.h"
-#include "gpio_if.h"
-
-#define RB_NAND_DATA (0x00)
-
-struct rb_nand_softc {
- struct nand_softc nand_dev;
- struct resource *sc_mem;
- int rid;
- device_t sc_gpio;
- uint32_t sc_rdy_pin;
- uint32_t sc_nce_pin;
- uint32_t sc_cle_pin;
- uint32_t sc_ale_pin;
-};
-
-static int rb_nand_attach(device_t);
-static int rb_nand_probe(device_t);
-static int rb_nand_send_command(device_t, uint8_t);
-static int rb_nand_send_address(device_t, uint8_t);
-static uint8_t rb_nand_read_byte(device_t);
-static void rb_nand_read_buf(device_t, void *, uint32_t);
-static void rb_nand_write_buf(device_t, void *, uint32_t);
-static int rb_nand_select_cs(device_t, uint8_t);
-static int rb_nand_read_rnb(device_t);
-
-static device_method_t rb_nand_methods[] = {
- DEVMETHOD(device_probe, rb_nand_probe),
- DEVMETHOD(device_attach, rb_nand_attach),
-
- DEVMETHOD(nfc_send_command, rb_nand_send_command),
- DEVMETHOD(nfc_send_address, rb_nand_send_address),
- DEVMETHOD(nfc_read_byte, rb_nand_read_byte),
- DEVMETHOD(nfc_read_buf, rb_nand_read_buf),
- DEVMETHOD(nfc_write_buf, rb_nand_write_buf),
- DEVMETHOD(nfc_select_cs, rb_nand_select_cs),
- DEVMETHOD(nfc_read_rnb, rb_nand_read_rnb),
-
- { 0, 0 },
-};
-
-static driver_t rb_nand_driver = {
- "nand",
- rb_nand_methods,
- sizeof(struct rb_nand_softc),
-};
-
-static devclass_t rb_nand_devclass;
-DRIVER_MODULE(rb_nand, ofwbus, rb_nand_driver, rb_nand_devclass, 0, 0);
-
-#if 0
-static const struct nand_ecc_data rb_ecc = {
- .eccsize = 6,
- .eccmode = NAND_ECC_SOFT,
- .eccbytes = 6,
- .eccpositions = { 8, 9, 10, 13, 14, 15 },
-};
-#endif
-
-/* Slicer operates on the NAND controller, so we have to find the chip. */
-static int
-rb_nand_slicer(device_t dev, const char *provider __unused,
- struct flash_slice *slices, int *nslices)
-{
- struct nand_chip *chip;
- device_t *children;
- int n;
-
- if (device_get_children(dev, &children, &n) != 0) {
- panic("Slicer called on controller with no child!");
- }
- dev = children[0];
- free(children, M_TEMP);
-
- if (device_get_children(dev, &children, &n) != 0) {
- panic("Slicer called on controller with nandbus but no child!");
- }
- dev = children[0];
- free(children, M_TEMP);
-
- chip = device_get_softc(dev);
- *nslices = 2;
- slices[0].base = 0;
- slices[0].size = 4 * 1024 * 1024;
- slices[0].label = "boot";
-
- slices[1].base = 4 * 1024 * 1024;
- slices[1].size = chip->ndisk->d_mediasize - slices[0].size;
- slices[1].label = "rootfs";
-
- return (0);
-}
-
-static int
-rb_nand_probe(device_t dev)
-{
- const char *device_type;
-
- device_type = ofw_bus_get_type(dev);
-
- if (!device_type || strcmp(device_type, "rb,nand"))
- return (ENXIO);
-
- device_set_desc(dev, "RouterBoard 333/600/800 NAND controller");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-rb_nand_attach(device_t dev)
-{
- struct rb_nand_softc *sc;
- phandle_t node;
- uint32_t ale[2],cle[2],nce[2],rdy[2];
- u_long size,start;
- int err;
-
- sc = device_get_softc(dev);
- node = ofw_bus_get_node(dev);
-
- if (OF_getprop(node, "ale", ale, sizeof(ale)) <= 0) {
- return (ENXIO);
- }
- if (OF_getprop(node, "cle", cle, sizeof(cle)) <= 0) {
- return (ENXIO);
- }
- if (OF_getprop(node, "nce", nce, sizeof(nce)) <= 0) {
- return (ENXIO);
- }
- if (OF_getprop(node, "rdy", rdy, sizeof(rdy)) <= 0) {
- return (ENXIO);
- }
-
- if (ale[0] != cle[0] || ale[0] != nce[0] || ale[0] != rdy[0]) {
- device_printf(dev, "GPIO handles for signals must match.\n");
- return (ENXIO);
- }
- sc->sc_ale_pin = ale[1];
- sc->sc_cle_pin = cle[1];
- sc->sc_nce_pin = nce[1];
- sc->sc_rdy_pin = rdy[1];
-
- sc->sc_gpio = OF_device_from_xref(ale[0]);
- if (sc->sc_gpio == NULL) {
- device_printf(dev, "No GPIO resource found!\n");
- return (ENXIO);
- }
-
- sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
- RF_ACTIVE);
- if (sc->sc_mem == NULL) {
- device_printf(dev, "could not allocate resources!\n");
- return (ENXIO);
- }
-
- start = rman_get_start(sc->sc_mem);
- size = rman_get_size(sc->sc_mem);
- if (law_enable(OCP85XX_TGTIF_LBC, start, size) != 0) {
- bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->sc_mem);
- device_printf(dev, "could not allocate local address window.\n");
- return (ENXIO);
- }
-
- flash_register_slicer(rb_nand_slicer, FLASH_SLICES_TYPE_NAND, TRUE);
-
- nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL);
-
- err = nandbus_create(dev);
-
- return (err);
-}
-
-static int
-rb_nand_send_command(device_t dev, uint8_t command)
-{
- struct rb_nand_softc *sc;
-
- nand_debug(NDBG_DRV,"rb_nand: send command %x", command);
-
- sc = device_get_softc(dev);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 1);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 0);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_nce_pin, 0);
- bus_write_1(sc->sc_mem, RB_NAND_DATA, command);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 0);
- return (0);
-}
-
-static int
-rb_nand_send_address(device_t dev, uint8_t addr)
-{
- struct rb_nand_softc *sc;
-
- nand_debug(NDBG_DRV,"rb_nand: send address %x", addr);
-
- sc = device_get_softc(dev);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 0);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 1);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_nce_pin, 0);
- bus_write_1(sc->sc_mem, RB_NAND_DATA, addr);
- GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 0);
- return (0);
-}
-
-static uint8_t
-rb_nand_read_byte(device_t dev)
-{
- struct rb_nand_softc *sc;
- uint8_t data;
-
- sc = device_get_softc(dev);
- data = bus_read_1(sc->sc_mem, RB_NAND_DATA);
-
- nand_debug(NDBG_DRV,"rb_nand: read %x", data);
-
- return (data);
-}
-
-static void
-rb_nand_read_buf(device_t dev, void* buf, uint32_t len)
-{
- struct rb_nand_softc *sc;
-
- sc = device_get_softc(dev);
-
- bus_read_region_1(sc->sc_mem, RB_NAND_DATA, buf, len);
-}
-
-static void
-rb_nand_write_buf(device_t dev, void* buf, uint32_t len)
-{
- struct rb_nand_softc *sc;
- int i;
- uint8_t *b = (uint8_t*)buf;
-
- sc = device_get_softc(dev);
-
- for (i = 0; i < len; i++) {
-#ifdef NAND_DEBUG
- if (!(i % 16))
- printf("%s", i == 0 ? "rb_nand:\n" : "\n");
- printf(" %x", b[i]);
- if (i == len - 1)
- printf("\n");
-#endif
- bus_write_1(sc->sc_mem, RB_NAND_DATA, b[i]);
- }
-}
-
-static int
-rb_nand_select_cs(device_t dev, uint8_t cs)
-{
-
- if (cs > 0)
- return (ENODEV);
-
- return (0);
-}
-
-static int
-rb_nand_read_rnb(device_t dev)
-{
- struct rb_nand_softc *sc;
- uint32_t rdy_bit;
-
- sc = device_get_softc(dev);
- GPIO_PIN_GET(sc->sc_gpio, sc->sc_rdy_pin, &rdy_bit);
-
- return (rdy_bit); /* ready */
-}