aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/conf/DB-78XXX3
-rw-r--r--sys/arm/conf/DB-88F6XXX3
-rw-r--r--sys/arm/conf/DREAMPLUG-10018
-rw-r--r--sys/arm/conf/NOTES.armv55
-rw-r--r--sys/arm/conf/SHEEVAPLUG3
-rw-r--r--sys/arm/conf/VYBRID3
-rw-r--r--sys/arm/freescale/vybrid/vf_nfc.c528
-rw-r--r--sys/arm/mv/files.arm71
-rw-r--r--sys/arm/mv/files.mv1
-rw-r--r--sys/cam/ata/ata_all.c25
-rw-r--r--sys/cam/ata/ata_all.h1
-rw-r--r--sys/cam/ata/ata_xpt.c23
-rw-r--r--sys/cam/scsi/scsi_da.c19
-rw-r--r--sys/conf/files33
-rw-r--r--sys/conf/files.powerpc2
-rw-r--r--sys/conf/kern.opts.mk1
-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
-rw-r--r--sys/fs/nandfs/bmap.c625
-rw-r--r--sys/fs/nandfs/bmap.h42
-rw-r--r--sys/fs/nandfs/nandfs.h312
-rw-r--r--sys/fs/nandfs/nandfs_alloc.c366
-rw-r--r--sys/fs/nandfs/nandfs_bmap.c232
-rw-r--r--sys/fs/nandfs/nandfs_buffer.c85
-rw-r--r--sys/fs/nandfs/nandfs_cleaner.c622
-rw-r--r--sys/fs/nandfs/nandfs_cpfile.c778
-rw-r--r--sys/fs/nandfs/nandfs_dat.c346
-rw-r--r--sys/fs/nandfs/nandfs_dir.c316
-rw-r--r--sys/fs/nandfs/nandfs_fs.h567
-rw-r--r--sys/fs/nandfs/nandfs_ifile.c215
-rw-r--r--sys/fs/nandfs/nandfs_mount.h52
-rw-r--r--sys/fs/nandfs/nandfs_segment.c1314
-rw-r--r--sys/fs/nandfs/nandfs_subr.c1091
-rw-r--r--sys/fs/nandfs/nandfs_subr.h240
-rw-r--r--sys/fs/nandfs/nandfs_sufile.c571
-rw-r--r--sys/fs/nandfs/nandfs_vfsops.c1601
-rw-r--r--sys/fs/nandfs/nandfs_vnops.c2454
-rw-r--r--sys/fs/smbfs/smbfs_io.c4
-rw-r--r--sys/geom/geom_flashmap.c24
-rw-r--r--sys/modules/Makefile7
-rw-r--r--sys/modules/nand/Makefile10
-rw-r--r--sys/modules/nandfs/Makefile12
-rw-r--r--sys/modules/nandsim/Makefile9
-rw-r--r--sys/sys/param.h2
69 files changed, 39 insertions, 21936 deletions
diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX
index b1379dfb544f..2007405751cc 100644
--- a/sys/arm/conf/DB-78XXX
+++ b/sys/arm/conf/DB-78XXX
@@ -74,9 +74,6 @@ device ds133x
# SATA
device mvs
-# NAND
-device nand
-
# GPIO
device gpio
diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX
index b0c36c0b1b42..64465baf4c77 100644
--- a/sys/arm/conf/DB-88F6XXX
+++ b/sys/arm/conf/DB-88F6XXX
@@ -78,9 +78,6 @@ device twsi
# SATA
device mvs
-# NAND
-device nand
-
# GPIO
device gpio
diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001
index 8a5ce4a6d8f2..18b2dee86fac 100644
--- a/sys/arm/conf/DREAMPLUG-1001
+++ b/sys/arm/conf/DREAMPLUG-1001
@@ -157,14 +157,6 @@ options ALTQ_PRIQ # Priority Queueing
options ALTQ_NOPCC # Required if the TSC is unusable
#options ALTQ_DEBUG
-# To use this configuration with the (rare) model 1001N (nand flash),
-# create a kernel config file that looks like this:
-#
-# include DREAMPLUG-1001
-# nomakeoptions FDT_DTS_FILE
-# makeoptions FDT_DTS_FILE=dreamplug-1001N.dts
-# device nand
-
# Flattened Device Tree
options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC
diff --git a/sys/arm/conf/NOTES.armv5 b/sys/arm/conf/NOTES.armv5
index c67b37ed0052..1e8825980448 100644
--- a/sys/arm/conf/NOTES.armv5
+++ b/sys/arm/conf/NOTES.armv5
@@ -31,8 +31,3 @@ options ARM_MANY_BOARD
options SOC_MV_DISCOVERY
options SOC_MV_KIRKWOOD
options SOC_MV_ORION
-
-# Add devices which are specific to various arm platforms...
-
-device nand
-
diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG
index df44533dcd72..b24a6d80a873 100644
--- a/sys/arm/conf/SHEEVAPLUG
+++ b/sys/arm/conf/SHEEVAPLUG
@@ -72,9 +72,6 @@ device scbus
device pass
device da
-# NAND
-device nand
-
# GPIO
device gpio
diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID
index a35a565711a2..318a7d0e3c68 100644
--- a/sys/arm/conf/VYBRID
+++ b/sys/arm/conf/VYBRID
@@ -37,7 +37,6 @@ options PLATFORM # Platform based SoC
#options BOOTP_WIRED_TO=ffec0
#options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/cosmic\"
-#options ROOTDEVNAME=\"nandfs:/dev/gnand0s.root\"
options ROOTDEVNAME=\"ufs:/dev/da0\"
options MUTEX_NOINLINE
@@ -80,8 +79,6 @@ device pass
#device atadisk
#device mvs
-device nand
-
# Serial ports
device uart
diff --git a/sys/arm/freescale/vybrid/vf_nfc.c b/sys/arm/freescale/vybrid/vf_nfc.c
deleted file mode 100644
index cdefa2564864..000000000000
--- a/sys/arm/freescale/vybrid/vf_nfc.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
- * 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.
- */
-
-/*
- * Vybrid Family NAND Flash Controller (NFC)
- * Chapter 31, Vybrid Reference Manual, Rev. 5, 07/2013
- */
-
-#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 <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-#include <dev/nand/nand.h>
-#include <dev/nand/nandbus.h>
-
-#include <machine/bus.h>
-
-#include "nfc_if.h"
-
-#include <arm/freescale/vybrid/vf_common.h>
-
-enum addr_type {
- ADDR_NONE,
- ADDR_ID,
- ADDR_ROW,
- ADDR_ROWCOL
-};
-
-struct fsl_nfc_fcm {
- uint32_t addr_bits;
- enum addr_type addr_type;
- uint32_t col_addr_bits;
- uint32_t row_addr_bits;
- u_int read_ptr;
- u_int addr_ptr;
- u_int command;
- u_int code;
-};
-
-struct vf_nand_softc {
- struct nand_softc nand_dev;
- bus_space_handle_t bsh;
- bus_space_tag_t bst;
- struct resource *res[2];
- struct fsl_nfc_fcm fcm;
-};
-
-static struct resource_spec nfc_spec[] = {
- { SYS_RES_MEMORY, 0, RF_ACTIVE },
- { SYS_RES_IRQ, 0, RF_ACTIVE },
- { -1, 0 }
-};
-
-static int vf_nand_attach(device_t);
-static int vf_nand_probe(device_t);
-static int vf_nand_send_command(device_t, uint8_t);
-static int vf_nand_send_address(device_t, uint8_t);
-static int vf_nand_start_command(device_t);
-static uint8_t vf_nand_read_byte(device_t);
-static void vf_nand_read_buf(device_t, void *, uint32_t);
-static void vf_nand_write_buf(device_t, void *, uint32_t);
-static int vf_nand_select_cs(device_t, uint8_t);
-static int vf_nand_read_rnb(device_t);
-
-#define CMD_READ_PAGE 0x7EE0
-#define CMD_PROG_PAGE 0x7FC0
-#define CMD_PROG_PAGE_DMA 0xFFC8
-#define CMD_ERASE 0x4EC0
-#define CMD_READ_ID 0x4804
-#define CMD_READ_STATUS 0x4068
-#define CMD_RESET 0x4040
-#define CMD_RANDOM_IN 0x7140
-#define CMD_RANDOM_OUT 0x70E0
-
-#define CMD_BYTE2_PROG_PAGE 0x10
-#define CMD_BYTE2_PAGE_READ 0x30
-#define CMD_BYTE2_ERASE 0xD0
-
-#define NFC_CMD1 0x3F00 /* Flash command 1 */
-#define NFC_CMD2 0x3F04 /* Flash command 2 */
-#define NFC_CAR 0x3F08 /* Column address */
-#define NFC_RAR 0x3F0C /* Row address */
-#define NFC_RPT 0x3F10 /* Flash command repeat */
-#define NFC_RAI 0x3F14 /* Row address increment */
-#define NFC_SR1 0x3F18 /* Flash status 1 */
-#define NFC_SR2 0x3F1C /* Flash status 2 */
-#define NFC_DMA_CH1 0x3F20 /* DMA channel 1 address */
-#define NFC_DMACFG 0x3F24 /* DMA configuration */
-#define NFC_SWAP 0x3F28 /* Cach swap */
-#define NFC_SECSZ 0x3F2C /* Sector size */
-#define NFC_CFG 0x3F30 /* Flash configuration */
-#define NFC_DMA_CH2 0x3F34 /* DMA channel 2 address */
-#define NFC_ISR 0x3F38 /* Interrupt status */
-
-#define ECCMODE_SHIFT 17
-#define AIAD_SHIFT 5
-#define AIBN_SHIFT 4
-#define PAGECOUNT_SHIFT 0
-#define BITWIDTH_SHIFT 7
-#define BITWIDTH8 0
-#define BITWIDTH16 1
-#define PAGECOUNT_MASK 0xf
-
-#define CMD2_BYTE1_SHIFT 24
-#define CMD2_CODE_SHIFT 8
-#define CMD2_BUFNO_SHIFT 1
-#define CMD2_START_SHIFT 0
-
-static device_method_t vf_nand_methods[] = {
- DEVMETHOD(device_probe, vf_nand_probe),
- DEVMETHOD(device_attach, vf_nand_attach),
- DEVMETHOD(nfc_start_command, vf_nand_start_command),
- DEVMETHOD(nfc_send_command, vf_nand_send_command),
- DEVMETHOD(nfc_send_address, vf_nand_send_address),
- DEVMETHOD(nfc_read_byte, vf_nand_read_byte),
- DEVMETHOD(nfc_read_buf, vf_nand_read_buf),
- DEVMETHOD(nfc_write_buf, vf_nand_write_buf),
- DEVMETHOD(nfc_select_cs, vf_nand_select_cs),
- DEVMETHOD(nfc_read_rnb, vf_nand_read_rnb),
- { 0, 0 },
-};
-
-static driver_t vf_nand_driver = {
- "nand",
- vf_nand_methods,
- sizeof(struct vf_nand_softc),
-};
-
-static devclass_t vf_nand_devclass;
-DRIVER_MODULE(vf_nand, simplebus, vf_nand_driver, vf_nand_devclass, 0, 0);
-
-static int
-vf_nand_probe(device_t dev)
-{
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (!ofw_bus_is_compatible(dev, "fsl,mvf600-nand"))
- return (ENXIO);
-
- device_set_desc(dev, "Vybrid Family NAND controller");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-vf_nand_attach(device_t dev)
-{
- struct vf_nand_softc *sc;
- int err;
- int reg;
-
- sc = device_get_softc(dev);
- if (bus_alloc_resources(dev, nfc_spec, sc->res)) {
- device_printf(dev, "could not allocate resources!\n");
- return (ENXIO);
- }
-
- sc->bst = rman_get_bustag(sc->res[0]);
- sc->bsh = rman_get_bushandle(sc->res[0]);
-
- /* Size in bytes of one elementary transfer unit */
- WRITE4(sc, NFC_SECSZ, 2048);
-
- /* Flash mode width */
- reg = READ4(sc, NFC_CFG);
- reg |= (BITWIDTH16 << BITWIDTH_SHIFT);
-
- /* No correction, ECC bypass */
- reg &= ~(0x7 << ECCMODE_SHIFT);
-
- /* Disable Auto-incrementing of flash row address */
- reg &= ~(0x1 << AIAD_SHIFT);
-
- /* Disable Auto-incrementing of buffer numbers */
- reg &= ~(0x1 << AIBN_SHIFT);
-
- /*
- * Number of virtual pages (in one physical flash page)
- * to be programmed or read, etc.
- */
- reg &= ~(PAGECOUNT_MASK);
- reg |= (1 << PAGECOUNT_SHIFT);
- WRITE4(sc, NFC_CFG, reg);
-
- nand_init(&sc->nand_dev, dev, NAND_ECC_NONE, 0, 0, NULL, NULL);
- err = nandbus_create(dev);
- return (err);
-}
-
-static int
-vf_nand_start_command(device_t dev)
-{
- struct vf_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- int reg;
-
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- nand_debug(NDBG_DRV,"vf_nand: start command %x", fcm->command);
-
- /* CMD2 */
- reg = READ4(sc, NFC_CMD2);
- reg &= ~(0xff << CMD2_BYTE1_SHIFT);
- reg |= (fcm->command << CMD2_BYTE1_SHIFT);
- WRITE4(sc, NFC_CMD2, reg);
-
- /* CMD1 */
- if ((fcm->command == NAND_CMD_READ) ||
- (fcm->command == NAND_CMD_PROG) ||
- (fcm->command == NAND_CMD_ERASE)) {
- reg = READ4(sc, NFC_CMD1);
- reg &= ~(0xff << 24);
-
- if (fcm->command == NAND_CMD_READ)
- reg |= (CMD_BYTE2_PAGE_READ << 24);
- else if (fcm->command == NAND_CMD_PROG)
- reg |= (CMD_BYTE2_PROG_PAGE << 24);
- else if (fcm->command == NAND_CMD_ERASE)
- reg |= (CMD_BYTE2_ERASE << 24);
-
- WRITE4(sc, NFC_CMD1, reg);
- }
-
- /* We work with 1st buffer */
- reg = READ4(sc, NFC_CMD2);
- reg &= ~(0xf << CMD2_BUFNO_SHIFT);
- reg |= (0 << CMD2_BUFNO_SHIFT);
- WRITE4(sc, NFC_CMD2, reg);
-
- /* Cmd CODE */
- reg = READ4(sc, NFC_CMD2);
- reg &= ~(0xffff << CMD2_CODE_SHIFT);
- reg |= (fcm->code << CMD2_CODE_SHIFT);
- WRITE4(sc, NFC_CMD2, reg);
-
- /* Col */
- if (fcm->addr_type == ADDR_ROWCOL) {
- reg = READ4(sc, NFC_CAR);
- reg &= ~(0xffff);
- reg |= fcm->col_addr_bits;
- nand_debug(NDBG_DRV,"setting CAR to 0x%08x\n", reg);
- WRITE4(sc, NFC_CAR, reg);
- }
-
- /* Row */
- reg = READ4(sc, NFC_RAR);
- reg &= ~(0xffffff);
- if (fcm->addr_type == ADDR_ID)
- reg |= fcm->addr_bits;
- else
- reg |= fcm->row_addr_bits;
- WRITE4(sc, NFC_RAR, reg);
-
- /* Start */
- reg = READ4(sc, NFC_CMD2);
- reg |= (1 << CMD2_START_SHIFT);
- WRITE4(sc, NFC_CMD2, reg);
-
- /* Wait command completion */
- while (READ4(sc, NFC_CMD2) & (1 << CMD2_START_SHIFT))
- ;
-
- return (0);
-}
-
-static int
-vf_nand_send_command(device_t dev, uint8_t command)
-{
- struct vf_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
-
- nand_debug(NDBG_DRV,"vf_nand: send command %x", command);
-
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- if ((command == NAND_CMD_READ_END) ||
- (command == NAND_CMD_PROG_END) ||
- (command == NAND_CMD_ERASE_END)) {
- return (0);
- }
-
- fcm->command = command;
-
- fcm->code = 0;
- fcm->read_ptr = 0;
- fcm->addr_type = 0;
- fcm->addr_bits = 0;
-
- fcm->addr_ptr = 0;
- fcm->col_addr_bits = 0;
- fcm->row_addr_bits = 0;
-
- switch (command) {
- case NAND_CMD_READ:
- fcm->code = CMD_READ_PAGE;
- fcm->addr_type = ADDR_ROWCOL;
- break;
- case NAND_CMD_PROG:
- fcm->code = CMD_PROG_PAGE;
- fcm->addr_type = ADDR_ROWCOL;
- break;
- case NAND_CMD_PROG_END:
- break;
- case NAND_CMD_ERASE_END:
- break;
- case NAND_CMD_RESET:
- fcm->code = CMD_RESET;
- break;
- case NAND_CMD_READ_ID:
- fcm->code = CMD_READ_ID;
- fcm->addr_type = ADDR_ID;
- break;
- case NAND_CMD_READ_PARAMETER:
- fcm->code = CMD_READ_PAGE;
- fcm->addr_type = ADDR_ID;
- break;
- case NAND_CMD_STATUS:
- fcm->code = CMD_READ_STATUS;
- break;
- case NAND_CMD_ERASE:
- fcm->code = CMD_ERASE;
- fcm->addr_type = ADDR_ROW;
- break;
- default:
- nand_debug(NDBG_DRV, "unknown command %d\n", command);
- return (1);
- }
-
- return (0);
-}
-
-static int
-vf_nand_send_address(device_t dev, uint8_t addr)
-{
- struct vf_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
-
- nand_debug(NDBG_DRV,"vf_nand: send address %x", addr);
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- nand_debug(NDBG_DRV, "setting addr #%d to 0x%02x\n", fcm->addr_ptr, addr);
-
- if (fcm->addr_type == ADDR_ID) {
- fcm->addr_bits = addr;
- } else if (fcm->addr_type == ADDR_ROWCOL) {
-
- if (fcm->addr_ptr < 2)
- fcm->col_addr_bits |= (addr << (fcm->addr_ptr * 8));
- else
- fcm->row_addr_bits |= (addr << ((fcm->addr_ptr - 2) * 8));
-
- } else if (fcm->addr_type == ADDR_ROW)
- fcm->row_addr_bits |= (addr << (fcm->addr_ptr * 8));
-
- fcm->addr_ptr += 1;
-
- return (0);
-}
-
-static uint8_t
-vf_nand_read_byte(device_t dev)
-{
- struct vf_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- uint8_t data;
- int sr1, sr2;
- int b;
-
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- sr1 = READ4(sc, NFC_SR1);
- sr2 = READ4(sc, NFC_SR2);
-
- data = 0;
- if (fcm->addr_type == ADDR_ID) {
- b = 32 - ((fcm->read_ptr + 1) * 8);
- data = (sr1 >> b) & 0xff;
- fcm->read_ptr++;
- } else if (fcm->command == NAND_CMD_STATUS) {
- data = sr2 & 0xff;
- }
-
- nand_debug(NDBG_DRV,"vf_nand: read %x", data);
- return (data);
-}
-
-static void
-vf_nand_read_buf(device_t dev, void* buf, uint32_t len)
-{
- struct vf_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- uint16_t *tmp;
- uint8_t *b;
- int i;
-
- b = (uint8_t*)buf;
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- nand_debug(NDBG_DRV, "vf_nand: read_buf len %d", len);
-
- if (fcm->command == NAND_CMD_READ_PARAMETER) {
- tmp = malloc(len, M_DEVBUF, M_NOWAIT);
- bus_read_region_2(sc->res[0], 0x0, tmp, len);
-
- for (i = 0; i < len; i += 2) {
- b[i] = tmp[i+1];
- b[i+1] = tmp[i];
- }
-
- free(tmp, M_DEVBUF);
-
-#ifdef NAND_DEBUG
- for (i = 0; i < len; i++) {
- if (!(i % 16))
- printf("%s", i == 0 ? "vf_nand:\n" : "\n");
- printf(" %x", b[i]);
- if (i == len - 1)
- printf("\n");
- }
-#endif
-
- } else {
-
- for (i = 0; i < len; i++) {
- b[i] = READ1(sc, i);
-
-#ifdef NAND_DEBUG
- if (!(i % 16))
- printf("%s", i == 0 ? "vf_nand:\n" : "\n");
- printf(" %x", b[i]);
- if (i == len - 1)
- printf("\n");
-#endif
- }
-
- }
-}
-
-static void
-vf_nand_write_buf(device_t dev, void* buf, uint32_t len)
-{
- struct vf_nand_softc *sc;
- struct fsl_nfc_fcm *fcm;
- uint8_t *b;
- int i;
-
- b = (uint8_t*)buf;
- sc = device_get_softc(dev);
- fcm = &sc->fcm;
-
- nand_debug(NDBG_DRV,"vf_nand: write_buf len %d", len);
-
- for (i = 0; i < len; i++) {
- WRITE1(sc, i, b[i]);
-
-#ifdef NAND_DEBUG
- if (!(i % 16))
- printf("%s", i == 0 ? "vf_nand:\n" : "\n");
- printf(" %x", b[i]);
- if (i == len - 1)
- printf("\n");
-#endif
-
- }
-}
-
-static int
-vf_nand_select_cs(device_t dev, uint8_t cs)
-{
-
- if (cs > 0)
- return (ENODEV);
-
- return (0);
-}
-
-static int
-vf_nand_read_rnb(device_t dev)
-{
-
- /* no-op */
- return (0); /* ready */
-}
diff --git a/sys/arm/mv/files.arm7 b/sys/arm/mv/files.arm7
index d27357480cae..a6138042bc80 100644
--- a/sys/arm/mv/files.arm7
+++ b/sys/arm/mv/files.arm7
@@ -29,7 +29,6 @@ dev/iicbus/twsi/mv_twsi.c optional twsi
dev/mge/if_mge.c optional mge
dev/neta/if_mvneta_fdt.c optional neta fdt
dev/neta/if_mvneta.c optional neta mdio mii
-dev/nand/nfc_mv.c optional nand
dev/mvs/mvs_soc.c optional mvs
dev/uart/uart_dev_ns8250.c optional uart
dev/uart/uart_dev_snps.c optional uart
diff --git a/sys/arm/mv/files.mv b/sys/arm/mv/files.mv
index ee027f059441..1dc45105450c 100644
--- a/sys/arm/mv/files.mv
+++ b/sys/arm/mv/files.mv
@@ -26,7 +26,6 @@ dev/iicbus/twsi/mv_twsi.c optional twsi
dev/mge/if_mge.c optional mge
dev/neta/if_mvneta_fdt.c optional neta fdt
dev/neta/if_mvneta.c optional neta mdio mii
-dev/nand/nfc_mv.c optional nand
dev/mvs/mvs_soc.c optional mvs
dev/uart/uart_dev_ns8250.c optional uart
dev/uart/uart_dev_snps.c optional uart
diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c
index 9a4cdbed071b..76d65ae5e405 100644
--- a/sys/cam/ata/ata_all.c
+++ b/sys/cam/ata/ata_all.c
@@ -1238,28 +1238,3 @@ ata_zac_mgmt_in(struct ccb_ataio *ataio, uint32_t retries,
ataio->aux = auxiliary;
}
}
-
-void
-ata_param_fixup(struct ata_params *ident_buf)
-{
- int16_t *ptr;
-
- for (ptr = (int16_t *)ident_buf;
- ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
- *ptr = le16toh(*ptr);
- }
- if (strncmp(ident_buf->model, "FX", 2) &&
- strncmp(ident_buf->model, "NEC", 3) &&
- strncmp(ident_buf->model, "Pioneer", 7) &&
- strncmp(ident_buf->model, "SHARP", 5)) {
- ata_bswap(ident_buf->model, sizeof(ident_buf->model));
- ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
- ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
- }
- ata_btrim(ident_buf->model, sizeof(ident_buf->model));
- ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
- ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
- ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
- ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
- ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
-}
diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h
index ca635253511c..087d6820f980 100644
--- a/sys/cam/ata/ata_all.h
+++ b/sys/cam/ata/ata_all.h
@@ -135,7 +135,6 @@ void ata_read_log(struct ccb_ataio *ataio, uint32_t retries,
uint16_t block_count, uint32_t protocol,
uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout);
-void ata_param_fixup(struct ata_params *ident_buf);
void ata_bswap(int8_t *buf, int len);
void ata_btrim(int8_t *buf, int len);
void ata_bpack(int8_t *src, int8_t *dst, int len);
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 017db8854b08..94dc435b099b 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -893,13 +893,14 @@ noerror:
case PROBE_IDENTIFY:
{
struct ccb_pathinq cpi;
+ int16_t *ptr;
int veto = 0;
- /*
- * Convert to host byte order, and fix the strings.
- */
ident_buf = &softc->ident_data;
- ata_param_fixup(ident_buf);
+ for (ptr = (int16_t *)ident_buf;
+ ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
+ *ptr = le16toh(*ptr);
+ }
/*
* Allow others to veto this ATA disk attachment. This
@@ -911,6 +912,20 @@ noerror:
goto device_fail;
}
+ if (strncmp(ident_buf->model, "FX", 2) &&
+ strncmp(ident_buf->model, "NEC", 3) &&
+ strncmp(ident_buf->model, "Pioneer", 7) &&
+ strncmp(ident_buf->model, "SHARP", 5)) {
+ ata_bswap(ident_buf->model, sizeof(ident_buf->model));
+ ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
+ ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
+ }
+ ata_btrim(ident_buf->model, sizeof(ident_buf->model));
+ ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
+ ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
+ ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
+ ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
+ ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
/* Device may need spin-up before IDENTIFY become valid. */
if ((ident_buf->specconf == 0x37c8 ||
ident_buf->specconf == 0x738c) &&
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index f2f60d35b2e2..a89c40e19a7b 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -64,9 +64,6 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_ccb.h>
#include <cam/cam_periph.h>
#include <cam/cam_xpt_periph.h>
-#ifdef _KERNEL
-#include <cam/cam_xpt_internal.h>
-#endif /* _KERNEL */
#include <cam/cam_sim.h>
#include <cam/cam_iosched.h>
@@ -3616,7 +3613,15 @@ out:
break;
}
- ata_params = &periph->path->device->ident_data;
+ ata_params = (struct ata_params*)
+ malloc(sizeof(*ata_params), M_SCSIDA,M_NOWAIT|M_ZERO);
+
+ if (ata_params == NULL) {
+ xpt_print(periph->path, "Couldn't malloc ata_params "
+ "data\n");
+ /* da_free_periph??? */
+ break;
+ }
scsi_ata_identify(&start_ccb->csio,
/*retries*/da_retry_count,
@@ -5187,7 +5192,7 @@ dadone_probeata(struct cam_periph *periph, union ccb *done_ccb)
struct da_softc *softc;
u_int32_t priority;
int continue_probe;
- int error;
+ int error, i;
int16_t *ptr;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probeata\n"));
@@ -5205,7 +5210,8 @@ dadone_probeata(struct cam_periph *periph, union ccb *done_ccb)
if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
uint16_t old_rate;
- ata_param_fixup(ata_params);
+ for (i = 0; i < sizeof(*ata_params) / 2; i++)
+ ptr[i] = le16toh(ptr[i]);
if (ata_params->support_dsm & ATA_SUPPORT_DSM_TRIM &&
(softc->quirks & DA_Q_NO_UNMAP) == 0) {
dadeleteflag(softc, DA_DELETE_ATA_TRIM, 1);
@@ -5289,6 +5295,7 @@ dadone_probeata(struct cam_periph *periph, union ccb *done_ccb)
}
}
+ free(ata_params, M_SCSIDA);
if ((softc->zone_mode == DA_ZONE_HOST_AWARE)
|| (softc->zone_mode == DA_ZONE_HOST_MANAGED)) {
/*
diff --git a/sys/conf/files b/sys/conf/files
index 96211a9fc623..c62a9e285e47 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1708,7 +1708,7 @@ dev/fdt/fdt_clock_if.m optional fdt fdt_clock
dev/fdt/fdt_common.c optional fdt
dev/fdt/fdt_pinctrl.c optional fdt fdt_pinctrl
dev/fdt/fdt_pinctrl_if.m optional fdt fdt_pinctrl
-dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand | fdt mx25l | fdt n25q | fdt at45d
+dev/fdt/fdt_slicer.c optional fdt cfi | fdt mx25l | fdt n25q | fdt at45d
dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \
dependency "${FDT_DTS_FILE:T:R}.dtb"
dev/fdt/simplebus.c optional fdt
@@ -2457,21 +2457,6 @@ dev/mxge/mxge_ethp_z8e.c optional mxge pci
dev/mxge/mxge_rss_eth_z8e.c optional mxge pci
dev/mxge/mxge_rss_ethp_z8e.c optional mxge pci
dev/my/if_my.c optional my
-dev/nand/nand.c optional nand
-dev/nand/nand_bbt.c optional nand
-dev/nand/nand_cdev.c optional nand
-dev/nand/nand_generic.c optional nand
-dev/nand/nand_geom.c optional nand
-dev/nand/nand_id.c optional nand
-dev/nand/nandbus.c optional nand
-dev/nand/nandbus_if.m optional nand
-dev/nand/nand_if.m optional nand
-dev/nand/nandsim.c optional nandsim nand
-dev/nand/nandsim_chip.c optional nandsim nand
-dev/nand/nandsim_ctrl.c optional nandsim nand
-dev/nand/nandsim_log.c optional nandsim nand
-dev/nand/nandsim_swap.c optional nandsim nand
-dev/nand/nfc_if.m optional nand
dev/netmap/if_ptnet.c optional netmap inet
dev/netmap/netmap.c optional netmap
dev/netmap/netmap_bdg.c optional netmap
@@ -3499,20 +3484,6 @@ fs/msdosfs/msdosfs_iconv.c optional msdosfs_iconv
fs/msdosfs/msdosfs_lookup.c optional msdosfs
fs/msdosfs/msdosfs_vfsops.c optional msdosfs
fs/msdosfs/msdosfs_vnops.c optional msdosfs
-fs/nandfs/bmap.c optional nandfs
-fs/nandfs/nandfs_alloc.c optional nandfs
-fs/nandfs/nandfs_bmap.c optional nandfs
-fs/nandfs/nandfs_buffer.c optional nandfs
-fs/nandfs/nandfs_cleaner.c optional nandfs
-fs/nandfs/nandfs_cpfile.c optional nandfs
-fs/nandfs/nandfs_dat.c optional nandfs
-fs/nandfs/nandfs_dir.c optional nandfs
-fs/nandfs/nandfs_ifile.c optional nandfs
-fs/nandfs/nandfs_segment.c optional nandfs
-fs/nandfs/nandfs_subr.c optional nandfs
-fs/nandfs/nandfs_sufile.c optional nandfs
-fs/nandfs/nandfs_vfsops.c optional nandfs
-fs/nandfs/nandfs_vnops.c optional nandfs
fs/nfs/nfs_commonkrpc.c optional nfscl | nfsd
fs/nfs/nfs_commonsubs.c optional nfscl | nfsd
fs/nfs/nfs_commonport.c optional nfscl | nfsd
@@ -3600,7 +3571,7 @@ geom/geom_disk.c standard
geom/geom_dump.c standard
geom/geom_event.c standard
geom/geom_fox.c optional geom_fox
-geom/geom_flashmap.c optional fdt cfi | fdt nand | fdt mx25l | mmcsd | fdt n25q | fdt at45d
+geom/geom_flashmap.c optional fdt cfi | fdt mx25l | mmcsd | fdt n25q | fdt at45d
geom/geom_io.c standard
geom/geom_kern.c standard
geom/geom_map.c optional geom_map
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index ade545c59cd6..5383595b1411 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -43,8 +43,6 @@ dev/iicbus/max6690.c optional max6690 powermac
dev/iicbus/ofw_iicbus.c optional iicbus aim
dev/ipmi/ipmi.c optional ipmi
dev/ipmi/ipmi_opal.c optional powernv ipmi
-dev/nand/nfc_fsl.c optional nand mpc85xx
-dev/nand/nfc_rb.c optional nand mpc85xx
# Most ofw stuff below is brought in by conf/files for options FDT, but
# we always want it, even on non-FDT platforms.
dev/fdt/simplebus.c standard
diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk
index 33aa0bcba989..58f125efbd06 100644
--- a/sys/conf/kern.opts.mk
+++ b/sys/conf/kern.opts.mk
@@ -52,7 +52,6 @@ __DEFAULT_YES_OPTIONS = \
__DEFAULT_NO_OPTIONS = \
EXTRA_TCP_STACKS \
KERNEL_RETPOLINE \
- NAND \
OFED \
RATELIMIT
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 */
-}
diff --git a/sys/fs/nandfs/bmap.c b/sys/fs/nandfs/bmap.c
deleted file mode 100644
index 5721cf0157bc..000000000000
--- a/sys/fs/nandfs/bmap.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/kernel.h>
-#include <sys/stat.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/signalvar.h>
-#include <sys/malloc.h>
-#include <sys/dirent.h>
-#include <sys/lockf.h>
-#include <sys/ktr.h>
-#include <sys/kdb.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-#include <vm/vnode_pager.h>
-
-#include <machine/_inttypes.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-#include <vm/vnode_pager.h>
-
-#include "nandfs_mount.h"
-#include "nandfs.h"
-#include "nandfs_subr.h"
-#include "bmap.h"
-
-static int bmap_getlbns(struct nandfs_node *, nandfs_lbn_t,
- struct nandfs_indir *, int *);
-
-int
-bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t *vblk)
-{
- struct nandfs_inode *ip;
- struct nandfs_indir a[NANDFS_NIADDR + 1], *ap;
- nandfs_daddr_t daddr;
- struct buf *bp;
- int error;
- int num, *nump;
-
- DPRINTF(BMAP, ("%s: node %p lblk %jx enter\n", __func__, node, lblk));
- ip = &node->nn_inode;
-
- ap = a;
- nump = &num;
-
- error = bmap_getlbns(node, lblk, ap, nump);
- if (error)
- return (error);
-
- if (num == 0) {
- *vblk = ip->i_db[lblk];
- return (0);
- }
-
- DPRINTF(BMAP, ("%s: node %p lblk=%jx trying ip->i_ib[%x]\n", __func__,
- node, lblk, ap->in_off));
- daddr = ip->i_ib[ap->in_off];
- for (bp = NULL, ++ap; --num; ap++) {
- if (daddr == 0) {
- DPRINTF(BMAP, ("%s: node %p lblk=%jx returning with "
- "vblk 0\n", __func__, node, lblk));
- *vblk = 0;
- return (0);
- }
- if (ap->in_lbn == lblk) {
- DPRINTF(BMAP, ("%s: node %p lblk=%jx ap->in_lbn=%jx "
- "returning address of indirect block (%jx)\n",
- __func__, node, lblk, ap->in_lbn, daddr));
- *vblk = daddr;
- return (0);
- }
-
- DPRINTF(BMAP, ("%s: node %p lblk=%jx reading block "
- "ap->in_lbn=%jx\n", __func__, node, lblk, ap->in_lbn));
-
- error = nandfs_bread_meta(node, ap->in_lbn, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- daddr = ((nandfs_daddr_t *)bp->b_data)[ap->in_off];
- brelse(bp);
- }
-
- DPRINTF(BMAP, ("%s: node %p lblk=%jx returning with %jx\n", __func__,
- node, lblk, daddr));
- *vblk = daddr;
-
- return (0);
-}
-
-int
-bmap_dirty_meta(struct nandfs_node *node, nandfs_lbn_t lblk, int force)
-{
- struct nandfs_indir a[NANDFS_NIADDR+1], *ap;
-#ifdef DEBUG
- nandfs_daddr_t daddr;
-#endif
- struct buf *bp;
- int error;
- int num, *nump;
-
- DPRINTF(BMAP, ("%s: node %p lblk=%jx\n", __func__, node, lblk));
-
- ap = a;
- nump = &num;
-
- error = bmap_getlbns(node, lblk, ap, nump);
- if (error)
- return (error);
-
- /*
- * Direct block, nothing to do
- */
- if (num == 0)
- return (0);
-
- DPRINTF(BMAP, ("%s: node %p reading blocks\n", __func__, node));
-
- for (bp = NULL, ++ap; --num; ap++) {
- error = nandfs_bread_meta(node, ap->in_lbn, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
-#ifdef DEBUG
- daddr = ((nandfs_daddr_t *)bp->b_data)[ap->in_off];
- MPASS(daddr != 0 || node->nn_ino == 3);
-#endif
-
- error = nandfs_dirty_buf_meta(bp, force);
- if (error)
- return (error);
- }
-
- return (0);
-}
-
-int
-bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk,
- nandfs_daddr_t vblk)
-{
- struct nandfs_inode *ip;
- struct nandfs_indir a[NANDFS_NIADDR+1], *ap;
- struct buf *bp;
- nandfs_daddr_t daddr;
- int error;
- int num, *nump, i;
-
- DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx\n", __func__, node, lblk,
- vblk));
-
- ip = &node->nn_inode;
-
- ap = a;
- nump = &num;
-
- error = bmap_getlbns(node, lblk, ap, nump);
- if (error)
- return (error);
-
- DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx got num=%d\n", __func__,
- node, lblk, vblk, num));
-
- if (num == 0) {
- DPRINTF(BMAP, ("%s: node %p lblk=%jx direct block\n", __func__,
- node, lblk));
- ip->i_db[lblk] = vblk;
- return (0);
- }
-
- DPRINTF(BMAP, ("%s: node %p lblk=%jx indirect block level %d\n",
- __func__, node, lblk, ap->in_off));
-
- if (num == 1) {
- DPRINTF(BMAP, ("%s: node %p lblk=%jx indirect block: inserting "
- "%jx as vblk for indirect block %d\n", __func__, node,
- lblk, vblk, ap->in_off));
- ip->i_ib[ap->in_off] = vblk;
- return (0);
- }
-
- bp = NULL;
- daddr = ip->i_ib[a[0].in_off];
- for (i = 1; i < num; i++) {
- if (bp)
- brelse(bp);
- if (daddr == 0) {
- DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx create "
- "block %jx %d\n", __func__, node, lblk, vblk,
- a[i].in_lbn, a[i].in_off));
- error = nandfs_bcreate_meta(node, a[i].in_lbn, NOCRED,
- 0, &bp);
- if (error)
- return (error);
- } else {
- DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx read "
- "block %jx %d\n", __func__, node, daddr, vblk,
- a[i].in_lbn, a[i].in_off));
- error = nandfs_bread_meta(node, a[i].in_lbn, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
- daddr = ((nandfs_daddr_t *)bp->b_data)[a[i].in_off];
- }
- i--;
-
- DPRINTF(BMAP,
- ("%s: bmap node %p lblk=%jx vblk=%jx inserting vblk level %d at "
- "offset %d at %jx\n", __func__, node, lblk, vblk, i, a[i].in_off,
- daddr));
-
- if (!bp) {
- nandfs_error("%s: cannot find indirect block\n", __func__);
- return (-1);
- }
- ((nandfs_daddr_t *)bp->b_data)[a[i].in_off] = vblk;
-
- error = nandfs_dirty_buf_meta(bp, 0);
- if (error) {
- nandfs_warning("%s: dirty failed buf: %p\n", __func__, bp);
- return (error);
- }
- DPRINTF(BMAP, ("%s: exiting node %p lblk=%jx vblk=%jx\n", __func__,
- node, lblk, vblk));
-
- return (error);
-}
-
-CTASSERT(NANDFS_NIADDR <= 3);
-#define SINGLE 0 /* index of single indirect block */
-#define DOUBLE 1 /* index of double indirect block */
-#define TRIPLE 2 /* index of triple indirect block */
-
-static __inline nandfs_lbn_t
-lbn_offset(struct nandfs_device *fsdev, int level)
-{
- nandfs_lbn_t res;
-
- for (res = 1; level > 0; level--)
- res *= MNINDIR(fsdev);
- return (res);
-}
-
-static nandfs_lbn_t
-blocks_inside(struct nandfs_device *fsdev, int level, struct nandfs_indir *nip)
-{
- nandfs_lbn_t blocks;
-
- for (blocks = 1; level >= SINGLE; level--, nip++) {
- MPASS(nip->in_off >= 0 && nip->in_off < MNINDIR(fsdev));
- blocks += nip->in_off * lbn_offset(fsdev, level);
- }
-
- return (blocks);
-}
-
-static int
-bmap_truncate_indirect(struct nandfs_node *node, int level, nandfs_lbn_t *left,
- int *cleaned, struct nandfs_indir *ap, struct nandfs_indir *fp,
- nandfs_daddr_t *copy)
-{
- struct buf *bp;
- nandfs_lbn_t i, lbn, nlbn, factor, tosub;
- struct nandfs_device *fsdev;
- int error, lcleaned, modified;
-
- DPRINTF(BMAP, ("%s: node %p level %d left %jx\n", __func__,
- node, level, *left));
-
- fsdev = node->nn_nandfsdev;
-
- MPASS(ap->in_off >= 0 && ap->in_off < MNINDIR(fsdev));
-
- factor = lbn_offset(fsdev, level);
- lbn = ap->in_lbn;
-
- error = nandfs_bread_meta(node, lbn, NOCRED, 0, &bp);
- if (error) {
- if (bp != NULL)
- brelse(bp);
- return (error);
- }
-
- bcopy(bp->b_data, copy, fsdev->nd_blocksize);
- bqrelse(bp);
-
- modified = 0;
-
- i = ap->in_off;
-
- if (ap != fp)
- ap++;
- for (nlbn = lbn + 1 - i * factor; i >= 0 && *left > 0; i--,
- nlbn += factor) {
- lcleaned = 0;
-
- DPRINTF(BMAP,
- ("%s: node %p i=%jx nlbn=%jx left=%jx ap=%p vblk %jx\n",
- __func__, node, i, nlbn, *left, ap, copy[i]));
-
- if (copy[i] == 0) {
- tosub = blocks_inside(fsdev, level - 1, ap);
- if (tosub > *left)
- tosub = 0;
-
- *left -= tosub;
- } else {
- if (level > SINGLE) {
- if (ap == fp)
- ap->in_lbn = nlbn;
-
- error = bmap_truncate_indirect(node, level - 1,
- left, &lcleaned, ap, fp,
- copy + MNINDIR(fsdev));
- if (error)
- return (error);
- } else {
- error = nandfs_bdestroy(node, copy[i]);
- if (error)
- return (error);
- lcleaned = 1;
- *left -= 1;
- }
- }
-
- if (lcleaned) {
- if (level > SINGLE) {
- error = nandfs_vblock_end(fsdev, copy[i]);
- if (error)
- return (error);
- }
- copy[i] = 0;
- modified++;
- }
-
- ap = fp;
- }
-
- if (i == -1)
- *cleaned = 1;
-
- error = nandfs_bread_meta(node, lbn, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- if (modified)
- bcopy(copy, bp->b_data, fsdev->nd_blocksize);
-
- /* Force success even if we can't dirty the buffer metadata when freeing space */
- nandfs_dirty_buf_meta(bp, 1);
-
- return (0);
-}
-
-int
-bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t lastblk,
- nandfs_lbn_t todo)
-{
- struct nandfs_inode *ip;
- struct nandfs_indir a[NANDFS_NIADDR + 1], f[NANDFS_NIADDR], *ap;
- nandfs_daddr_t indir_lbn[NANDFS_NIADDR];
- nandfs_daddr_t *copy;
- int error, level;
- nandfs_lbn_t left, tosub;
- struct nandfs_device *fsdev;
- int cleaned, i;
- int num, *nump;
-
- DPRINTF(BMAP, ("%s: node %p lastblk %jx truncating by %jx\n", __func__,
- node, lastblk, todo));
-
- ip = &node->nn_inode;
- fsdev = node->nn_nandfsdev;
-
- ap = a;
- nump = &num;
-
- error = bmap_getlbns(node, lastblk, ap, nump);
- if (error)
- return (error);
-
- indir_lbn[SINGLE] = -NANDFS_NDADDR;
- indir_lbn[DOUBLE] = indir_lbn[SINGLE] - MNINDIR(fsdev) - 1;
- indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - MNINDIR(fsdev)
- * MNINDIR(fsdev) - 1;
-
- for (i = 0; i < NANDFS_NIADDR; i++) {
- f[i].in_off = MNINDIR(fsdev) - 1;
- f[i].in_lbn = 0xdeadbeef;
- }
-
- left = todo;
-
-#ifdef DEBUG
- a[num].in_off = -1;
-#endif
-
- ap++;
- num -= 2;
-
- if (num < 0)
- goto direct;
-
- copy = malloc(MNINDIR(fsdev) * sizeof(nandfs_daddr_t) * (num + 1),
- M_NANDFSTEMP, M_WAITOK);
-
- for (level = num; level >= SINGLE && left > 0; level--) {
- cleaned = 0;
-
- if (ip->i_ib[level] == 0) {
- tosub = blocks_inside(fsdev, level, ap);
- if (tosub > left)
- left = 0;
- else
- left -= tosub;
- } else {
- if (ap == f)
- ap->in_lbn = indir_lbn[level];
- error = bmap_truncate_indirect(node, level, &left,
- &cleaned, ap, f, copy);
- if (error) {
- free(copy, M_NANDFSTEMP);
- nandfs_error("%s: error %d when truncate "
- "at level %d\n", __func__, error, level);
- return (error);
- }
- }
-
- if (cleaned) {
- nandfs_vblock_end(fsdev, ip->i_ib[level]);
- ip->i_ib[level] = 0;
- }
-
- ap = f;
- }
-
- free(copy, M_NANDFSTEMP);
-
-direct:
- if (num < 0)
- i = lastblk;
- else
- i = NANDFS_NDADDR - 1;
-
- for (; i >= 0 && left > 0; i--) {
- if (ip->i_db[i] != 0) {
- error = nandfs_bdestroy(node, ip->i_db[i]);
- if (error) {
- nandfs_error("%s: cannot destroy "
- "block %jx, error %d\n", __func__,
- (uintmax_t)ip->i_db[i], error);
- return (error);
- }
- ip->i_db[i] = 0;
- }
-
- left--;
- }
-
- KASSERT(left == 0,
- ("truncated wrong number of blocks (%jd should be 0)", left));
-
- return (error);
-}
-
-nandfs_lbn_t
-get_maxfilesize(struct nandfs_device *fsdev)
-{
- struct nandfs_indir f[NANDFS_NIADDR];
- nandfs_lbn_t max;
- int i;
-
- max = NANDFS_NDADDR;
-
- for (i = 0; i < NANDFS_NIADDR; i++) {
- f[i].in_off = MNINDIR(fsdev) - 1;
- max += blocks_inside(fsdev, i, f);
- }
-
- max *= fsdev->nd_blocksize;
-
- return (max);
-}
-
-/*
- * This is ufs_getlbns with minor modifications.
- */
-/*
- * Create an array of logical block number/offset pairs which represent the
- * path of indirect blocks required to access a data block. The first "pair"
- * contains the logical block number of the appropriate single, double or
- * triple indirect block and the offset into the inode indirect block array.
- * Note, the logical block number of the inode single/double/triple indirect
- * block appears twice in the array, once with the offset into the i_ib and
- * once with the offset into the page itself.
- */
-static int
-bmap_getlbns(struct nandfs_node *node, nandfs_lbn_t bn, struct nandfs_indir *ap, int *nump)
-{
- nandfs_daddr_t blockcnt;
- nandfs_lbn_t metalbn, realbn;
- struct nandfs_device *fsdev;
- int i, numlevels, off;
-
- fsdev = node->nn_nandfsdev;
-
- DPRINTF(BMAP, ("%s: node %p bn=%jx mnindir=%zd enter\n", __func__,
- node, bn, MNINDIR(fsdev)));
-
- if (nump)
- *nump = 0;
- numlevels = 0;
- realbn = bn;
-
- if (bn < 0)
- bn = -bn;
-
- /* The first NANDFS_NDADDR blocks are direct blocks. */
- if (bn < NANDFS_NDADDR)
- return (0);
-
- /*
- * Determine the number of levels of indirection. After this loop
- * is done, blockcnt indicates the number of data blocks possible
- * at the previous level of indirection, and NANDFS_NIADDR - i is the
- * number of levels of indirection needed to locate the requested block.
- */
- for (blockcnt = 1, i = NANDFS_NIADDR, bn -= NANDFS_NDADDR;; i--, bn -= blockcnt) {
- DPRINTF(BMAP, ("%s: blockcnt=%jd i=%d bn=%jd\n", __func__,
- blockcnt, i, bn));
- if (i == 0)
- return (EFBIG);
- blockcnt *= MNINDIR(fsdev);
- if (bn < blockcnt)
- break;
- }
-
- /* Calculate the address of the first meta-block. */
- if (realbn >= 0)
- metalbn = -(realbn - bn + NANDFS_NIADDR - i);
- else
- metalbn = -(-realbn - bn + NANDFS_NIADDR - i);
-
- /*
- * At each iteration, off is the offset into the bap array which is
- * an array of disk addresses at the current level of indirection.
- * The logical block number and the offset in that block are stored
- * into the argument array.
- */
- ap->in_lbn = metalbn;
- ap->in_off = off = NANDFS_NIADDR - i;
-
- DPRINTF(BMAP, ("%s: initial: ap->in_lbn=%jx ap->in_off=%d\n", __func__,
- metalbn, off));
-
- ap++;
- for (++numlevels; i <= NANDFS_NIADDR; i++) {
- /* If searching for a meta-data block, quit when found. */
- if (metalbn == realbn)
- break;
-
- blockcnt /= MNINDIR(fsdev);
- off = (bn / blockcnt) % MNINDIR(fsdev);
-
- ++numlevels;
- ap->in_lbn = metalbn;
- ap->in_off = off;
-
- DPRINTF(BMAP, ("%s: in_lbn=%jx in_off=%d\n", __func__,
- ap->in_lbn, ap->in_off));
- ++ap;
-
- metalbn -= -1 + off * blockcnt;
- }
- if (nump)
- *nump = numlevels;
-
- DPRINTF(BMAP, ("%s: numlevels=%d\n", __func__, numlevels));
-
- return (0);
-}
diff --git a/sys/fs/nandfs/bmap.h b/sys/fs/nandfs/bmap.h
deleted file mode 100644
index a4784f7a88f9..000000000000
--- a/sys/fs/nandfs/bmap.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _BMAP_H
-#define _BMAP_H
-
-#include "nandfs_fs.h"
-
-int bmap_lookup(struct nandfs_node *, nandfs_lbn_t, nandfs_daddr_t *);
-int bmap_insert_block(struct nandfs_node *, nandfs_lbn_t, nandfs_daddr_t);
-int bmap_truncate_mapping(struct nandfs_node *, nandfs_lbn_t, nandfs_lbn_t);
-int bmap_dirty_meta(struct nandfs_node *, nandfs_lbn_t, int);
-
-nandfs_lbn_t get_maxfilesize(struct nandfs_device *);
-
-#endif /* _BMAP_H */
diff --git a/sys/fs/nandfs/nandfs.h b/sys/fs/nandfs/nandfs.h
deleted file mode 100644
index 9a9b28a1bc0b..000000000000
--- a/sys/fs/nandfs/nandfs.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs.h,v 1.1 2009/07/18 16:31:42 reinoud
- *
- * $FreeBSD$
- */
-
-#ifndef _FS_NANDFS_NANDFS_H_
-#define _FS_NANDFS_NANDFS_H_
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/condvar.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-
-#include <sys/queue.h>
-#include <sys/uio.h>
-#include <sys/mutex.h>
-
-#include <sys/disk.h>
-#include <sys/kthread.h>
-#include "nandfs_fs.h"
-
-MALLOC_DECLARE(M_NANDFSTEMP);
-
-/* Debug categories */
-#define NANDFS_DEBUG_VOLUMES 0x000001
-#define NANDFS_DEBUG_BLOCK 0x000004
-#define NANDFS_DEBUG_LOCKING 0x000008
-#define NANDFS_DEBUG_NODE 0x000010
-#define NANDFS_DEBUG_LOOKUP 0x000020
-#define NANDFS_DEBUG_READDIR 0x000040
-#define NANDFS_DEBUG_TRANSLATE 0x000080
-#define NANDFS_DEBUG_STRATEGY 0x000100
-#define NANDFS_DEBUG_READ 0x000200
-#define NANDFS_DEBUG_WRITE 0x000400
-#define NANDFS_DEBUG_IFILE 0x000800
-#define NANDFS_DEBUG_ATTR 0x001000
-#define NANDFS_DEBUG_EXTATTR 0x002000
-#define NANDFS_DEBUG_ALLOC 0x004000
-#define NANDFS_DEBUG_CPFILE 0x008000
-#define NANDFS_DEBUG_DIRHASH 0x010000
-#define NANDFS_DEBUG_NOTIMPL 0x020000
-#define NANDFS_DEBUG_SHEDULE 0x040000
-#define NANDFS_DEBUG_SEG 0x080000
-#define NANDFS_DEBUG_SYNC 0x100000
-#define NANDFS_DEBUG_PARANOIA 0x200000
-#define NANDFS_DEBUG_VNCALL 0x400000
-#define NANDFS_DEBUG_BUF 0x1000000
-#define NANDFS_DEBUG_BMAP 0x2000000
-#define NANDFS_DEBUG_DAT 0x4000000
-#define NANDFS_DEBUG_GENERIC 0x8000000
-#define NANDFS_DEBUG_CLEAN 0x10000000
-
-extern int nandfs_verbose;
-
-#define DPRINTF(name, arg) { \
- if (nandfs_verbose & NANDFS_DEBUG_##name) {\
- printf arg;\
- };\
- }
-#define DPRINTFIF(name, cond, arg) { \
- if (nandfs_verbose & NANDFS_DEBUG_##name) { \
- if (cond) printf arg;\
- };\
- }
-
-#define VFSTONANDFS(mp) ((struct nandfsmount *)((mp)->mnt_data))
-#define VTON(vp) ((struct nandfs_node *)(vp)->v_data)
-#define NTOV(xp) ((xp)->nn_vnode)
-
-int nandfs_init(struct vfsconf *);
-int nandfs_uninit(struct vfsconf *);
-
-extern struct vop_vector nandfs_vnodeops;
-extern struct vop_vector nandfs_system_vnodeops;
-
-struct nandfs_node;
-
-/* Structure and derivatives */
-struct nandfs_mdt {
- uint32_t entries_per_block;
- uint32_t entries_per_group;
- uint32_t blocks_per_group;
- uint32_t groups_per_desc_block; /* desc is super group */
- uint32_t blocks_per_desc_block; /* desc is super group */
-};
-
-struct nandfs_segment {
- LIST_ENTRY(nandfs_segment) seg_link;
-
- struct nandfs_device *fsdev;
-
- TAILQ_HEAD(, buf) segsum;
- TAILQ_HEAD(, buf) data;
-
- uint64_t seg_num;
- uint64_t seg_next;
- uint64_t start_block;
- uint32_t num_blocks;
-
- uint32_t nblocks;
- uint32_t nbinfos;
- uint32_t segsum_blocks;
- uint32_t segsum_bytes;
- uint32_t bytes_left;
- char *current_off;
-};
-
-struct nandfs_seginfo {
- LIST_HEAD( ,nandfs_segment) seg_list;
- struct nandfs_segment *curseg;
- struct nandfs_device *fsdev;
- uint32_t blocks;
- uint8_t reiterate;
-};
-
-#define NANDFS_FSSTOR_FAILED 1
-struct nandfs_fsarea {
- int offset;
- int flags;
- int last_used;
-};
-
-extern int nandfs_cleaner_enable;
-extern int nandfs_cleaner_interval;
-extern int nandfs_cleaner_segments;
-
-struct nandfs_device {
- struct vnode *nd_devvp;
- struct g_consumer *nd_gconsumer;
-
- struct thread *nd_syncer;
- struct thread *nd_cleaner;
- int nd_syncer_exit;
- int nd_cleaner_exit;
-
- struct nandfs_fsarea nd_fsarea[NANDFS_NFSAREAS];
- int nd_last_fsarea;
-
- STAILQ_HEAD(nandfs_mnts, nandfsmount) nd_mounts;
- SLIST_ENTRY(nandfs_device) nd_next_device;
-
- /* FS structures */
- struct nandfs_fsdata nd_fsdata;
- struct nandfs_super_block nd_super;
- struct nandfs_segment_summary nd_last_segsum;
- struct nandfs_super_root nd_super_root;
- struct nandfs_node *nd_dat_node;
- struct nandfs_node *nd_cp_node;
- struct nandfs_node *nd_su_node;
- struct nandfs_node *nd_gc_node;
-
- struct nandfs_mdt nd_dat_mdt;
- struct nandfs_mdt nd_ifile_mdt;
-
- struct timespec nd_ts;
-
- /* Synchronization */
- struct mtx nd_mutex;
- struct mtx nd_sync_mtx;
- struct cv nd_sync_cv;
- struct mtx nd_clean_mtx;
- struct cv nd_clean_cv;
- struct lock nd_seg_const;
-
- struct nandfs_seginfo *nd_seginfo;
-
- /* FS geometry */
- uint64_t nd_devsize;
- uint64_t nd_maxfilesize;
- uint32_t nd_blocksize;
- uint32_t nd_erasesize;
-
- uint32_t nd_devblocksize;
-
- uint32_t nd_segs_reserved;
-
- /* Segment usage */
- uint64_t nd_clean_segs;
- uint64_t *nd_free_base;
- uint64_t nd_free_count;
- uint64_t nd_dirty_bufs;
-
- /* Running values */
- uint64_t nd_seg_sequence;
- uint64_t nd_seg_num;
- uint64_t nd_next_seg_num;
- uint64_t nd_last_pseg;
- uint64_t nd_last_cno;
- uint64_t nd_last_ino;
- uint64_t nd_fakevblk;
-
- int nd_mount_state;
- int nd_refcnt;
- int nd_syncing;
- int nd_cleaning;
-};
-
-extern SLIST_HEAD(_nandfs_devices, nandfs_device) nandfs_devices;
-
-#define NANDFS_FORCE_SYNCER 0x1
-#define NANDFS_UMOUNT 0x2
-
-#define SYNCER_UMOUNT 0x0
-#define SYNCER_VFS_SYNC 0x1
-#define SYNCER_BDFLUSH 0x2
-#define SYNCER_FFORCE 0x3
-#define SYNCER_FSYNC 0x4
-#define SYNCER_ROUPD 0x5
-
-static __inline int
-nandfs_writelockflags(struct nandfs_device *fsdev, int flags)
-{
- int error = 0;
-
- if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE)
- error = lockmgr(&fsdev->nd_seg_const, flags | LK_SHARED, NULL);
-
- return (error);
-}
-
-static __inline void
-nandfs_writeunlock(struct nandfs_device *fsdev)
-{
-
- if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE)
- lockmgr(&(fsdev)->nd_seg_const, LK_RELEASE, NULL);
-}
-
-#define NANDFS_WRITELOCKFLAGS(fsdev, flags) nandfs_writelockflags(fsdev, flags)
-
-#define NANDFS_WRITELOCK(fsdev) NANDFS_WRITELOCKFLAGS(fsdev, 0)
-
-#define NANDFS_WRITEUNLOCK(fsdev) nandfs_writeunlock(fsdev)
-
-#define NANDFS_WRITEASSERT(fsdev) lockmgr_assert(&(fsdev)->nd_seg_const, KA_LOCKED)
-
-/* Specific mountpoint; head or a checkpoint/snapshot */
-struct nandfsmount {
- STAILQ_ENTRY(nandfsmount) nm_next_mount;
-
- struct mount *nm_vfs_mountp;
- struct nandfs_device *nm_nandfsdev;
- struct nandfs_args nm_mount_args;
- struct nandfs_node *nm_ifile_node;
-
- uint8_t nm_flags;
- int8_t nm_ronly;
-};
-
-struct nandfs_node {
- struct vnode *nn_vnode;
- struct nandfsmount *nn_nmp;
- struct nandfs_device *nn_nandfsdev;
- struct lockf *nn_lockf;
-
- uint64_t nn_ino;
- struct nandfs_inode nn_inode;
-
- uint64_t nn_diroff;
- uint32_t nn_flags;
-};
-
-#define IN_ACCESS 0x0001 /* Inode access time update request */
-#define IN_CHANGE 0x0002 /* Inode change time update request */
-#define IN_UPDATE 0x0004 /* Inode was written to; update mtime*/
-#define IN_MODIFIED 0x0008 /* node has been modified */
-#define IN_RENAME 0x0010 /* node is being renamed. */
-
-/* File permissions. */
-#define IEXEC 0000100 /* Executable. */
-#define IWRITE 0000200 /* Writeable. */
-#define IREAD 0000400 /* Readable. */
-#define ISVTX 0001000 /* Sticky bit. */
-#define ISGID 0002000 /* Set-gid. */
-#define ISUID 0004000 /* Set-uid. */
-
-#define PRINT_NODE_FLAGS \
- "\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFIED\5IN_RENAME"
-
-#define NANDFS_GATHER(x) ((x)->b_flags |= B_FS_FLAG1)
-#define NANDFS_UNGATHER(x) ((x)->b_flags &= ~B_FS_FLAG1)
-#define NANDFS_ISGATHERED(x) ((x)->b_flags & B_FS_FLAG1)
-
-#endif /* !_FS_NANDFS_NANDFS_H_ */
diff --git a/sys/fs/nandfs/nandfs_alloc.c b/sys/fs/nandfs/nandfs_alloc.c
deleted file mode 100644
index afff174d130d..000000000000
--- a/sys/fs/nandfs/nandfs_alloc.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/sysctl.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-static void
-nandfs_get_desc_block_nr(struct nandfs_mdt *mdt, uint64_t desc,
- uint64_t *desc_block)
-{
-
- *desc_block = desc * mdt->blocks_per_desc_block;
-}
-
-static void
-nandfs_get_group_block_nr(struct nandfs_mdt *mdt, uint64_t group,
- uint64_t *group_block)
-{
- uint64_t desc, group_off;
-
- desc = group / mdt->groups_per_desc_block;
- group_off = group % mdt->groups_per_desc_block;
- *group_block = desc * mdt->blocks_per_desc_block +
- 1 + group_off * mdt->blocks_per_group;
-}
-
-static void
-init_desc_block(struct nandfs_mdt *mdt, uint8_t *block_data)
-{
- struct nandfs_block_group_desc *desc;
- uint32_t i;
-
- desc = (struct nandfs_block_group_desc *) block_data;
- for (i = 0; i < mdt->groups_per_desc_block; i++)
- desc[i].bg_nfrees = mdt->entries_per_group;
-}
-
-int
-nandfs_find_free_entry(struct nandfs_mdt *mdt, struct nandfs_node *node,
- struct nandfs_alloc_request *req)
-{
- nandfs_daddr_t desc, group, maxgroup, maxdesc, pos = 0;
- nandfs_daddr_t start_group, start_desc;
- nandfs_daddr_t desc_block, group_block;
- nandfs_daddr_t file_blocks;
- struct nandfs_block_group_desc *descriptors;
- struct buf *bp, *bp2;
- uint32_t *mask, i, mcount, msize;
- int error;
-
- file_blocks = node->nn_inode.i_blocks;
- maxgroup = 0x100000000ull / mdt->entries_per_group;
- maxdesc = maxgroup / mdt->groups_per_desc_block;
- start_group = req->entrynum / mdt->entries_per_group;
- start_desc = start_group / mdt->groups_per_desc_block;
-
- bp = bp2 = NULL;
-restart:
- for (desc = start_desc; desc < maxdesc; desc++) {
- nandfs_get_desc_block_nr(mdt, desc, &desc_block);
-
- if (bp)
- brelse(bp);
- if (desc_block < file_blocks) {
- error = nandfs_bread(node, desc_block, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- } else {
- error = nandfs_bcreate(node, desc_block, NOCRED, 0,
- &bp);
- if (error)
- return (error);
- file_blocks++;
- init_desc_block(mdt, bp->b_data);
- }
-
- descriptors = (struct nandfs_block_group_desc *) bp->b_data;
- for (group = start_group; group < mdt->groups_per_desc_block;
- group++) {
- if (descriptors[group].bg_nfrees > 0) {
- nandfs_get_group_block_nr(mdt, group,
- &group_block);
-
- if (bp2)
- brelse(bp2);
- if (group_block < file_blocks) {
- error = nandfs_bread(node, group_block,
- NOCRED, 0, &bp2);
- if (error) {
- brelse(bp);
- return (error);
- }
- } else {
- error = nandfs_bcreate(node,
- group_block, NOCRED, 0, &bp2);
- if (error)
- return (error);
- file_blocks++;
- }
- mask = (uint32_t *)bp2->b_data;
- msize = (sizeof(uint32_t) * __CHAR_BIT);
- mcount = mdt->entries_per_group / msize;
- for (i = 0; i < mcount; i++) {
- if (mask[i] == UINT32_MAX)
- continue;
-
- pos = ffs(~mask[i]) - 1;
- pos += (msize * i);
- pos += (group * mdt->entries_per_group);
- pos += desc * group *
- mdt->groups_per_desc_block *
- mdt->entries_per_group;
- goto found;
- }
- }
- }
- start_group = 0;
- }
-
- if (start_desc != 0) {
- maxdesc = start_desc;
- start_desc = 0;
- req->entrynum = 0;
- goto restart;
- }
-
- return (ENOENT);
-
-found:
- req->entrynum = pos;
- req->bp_desc = bp;
- req->bp_bitmap = bp2;
- DPRINTF(ALLOC, ("%s: desc: %p bitmap: %p entry: %#jx\n",
- __func__, req->bp_desc, req->bp_bitmap, (uintmax_t)pos));
-
- return (0);
-}
-
-int
-nandfs_find_entry(struct nandfs_mdt* mdt, struct nandfs_node *nnode,
- struct nandfs_alloc_request *req)
-{
- uint64_t dblock, bblock, eblock;
- uint32_t offset;
- int error;
-
- nandfs_mdt_trans_blk(mdt, req->entrynum, &dblock, &bblock, &eblock,
- &offset);
-
- error = nandfs_bread(nnode, dblock, NOCRED, 0, &req->bp_desc);
- if (error) {
- brelse(req->bp_desc);
- return (error);
- }
-
- error = nandfs_bread(nnode, bblock, NOCRED, 0, &req->bp_bitmap);
- if (error) {
- brelse(req->bp_desc);
- brelse(req->bp_bitmap);
- return (error);
- }
-
- error = nandfs_bread(nnode, eblock, NOCRED, 0, &req->bp_entry);
- if (error) {
- brelse(req->bp_desc);
- brelse(req->bp_bitmap);
- brelse(req->bp_entry);
- return (error);
- }
-
- DPRINTF(ALLOC,
- ("%s: desc_buf: %p bitmap_buf %p entry_buf %p offset %x\n",
- __func__, req->bp_desc, req->bp_bitmap, req->bp_entry, offset));
-
- return (0);
-}
-
-static __inline void
-nandfs_calc_idx_entry(struct nandfs_mdt* mdt, uint32_t entrynum,
- uint64_t *group, uint64_t *bitmap_idx, uint64_t *bitmap_off)
-{
-
- /* Find group_desc index */
- entrynum = entrynum %
- (mdt->entries_per_group * mdt->groups_per_desc_block);
- *group = entrynum / mdt->entries_per_group;
- /* Find bitmap index and bit offset */
- entrynum = entrynum % mdt->entries_per_group;
- *bitmap_idx = entrynum / (sizeof(uint32_t) * __CHAR_BIT);
- *bitmap_off = entrynum % (sizeof(uint32_t) * __CHAR_BIT);
-}
-
-int
-nandfs_free_entry(struct nandfs_mdt* mdt, struct nandfs_alloc_request *req)
-{
- struct nandfs_block_group_desc *descriptors;
- uint64_t bitmap_idx, bitmap_off;
- uint64_t group;
- uint32_t *mask, maskrw;
-
- nandfs_calc_idx_entry(mdt, req->entrynum, &group, &bitmap_idx,
- &bitmap_off);
-
- DPRINTF(ALLOC, ("nandfs_free_entry: req->entrynum=%jx bitmap_idx=%jx"
- " bitmap_off=%jx group=%jx\n", (uintmax_t)req->entrynum,
- (uintmax_t)bitmap_idx, (uintmax_t)bitmap_off, (uintmax_t)group));
-
- /* Update counter of free entries for group */
- descriptors = (struct nandfs_block_group_desc *) req->bp_desc->b_data;
- descriptors[group].bg_nfrees++;
-
- /* Set bit to indicate that entry is taken */
- mask = (uint32_t *)req->bp_bitmap->b_data;
- maskrw = mask[bitmap_idx];
- KASSERT(maskrw & (1 << bitmap_off), ("freeing unallocated vblock"));
- maskrw &= ~(1 << bitmap_off);
- mask[bitmap_idx] = maskrw;
-
- /* Make descriptor, bitmap and entry buffer dirty */
- if (nandfs_dirty_buf(req->bp_desc, 0) == 0) {
- nandfs_dirty_buf(req->bp_bitmap, 1);
- nandfs_dirty_buf(req->bp_entry, 1);
- } else {
- brelse(req->bp_bitmap);
- brelse(req->bp_entry);
- return (-1);
- }
-
- return (0);
-}
-
-int
-nandfs_alloc_entry(struct nandfs_mdt* mdt, struct nandfs_alloc_request *req)
-{
- struct nandfs_block_group_desc *descriptors;
- uint64_t bitmap_idx, bitmap_off;
- uint64_t group;
- uint32_t *mask, maskrw;
-
- nandfs_calc_idx_entry(mdt, req->entrynum, &group, &bitmap_idx,
- &bitmap_off);
-
- DPRINTF(ALLOC, ("nandfs_alloc_entry: req->entrynum=%jx bitmap_idx=%jx"
- " bitmap_off=%jx group=%jx\n", (uintmax_t)req->entrynum,
- (uintmax_t)bitmap_idx, (uintmax_t)bitmap_off, (uintmax_t)group));
-
- /* Update counter of free entries for group */
- descriptors = (struct nandfs_block_group_desc *) req->bp_desc->b_data;
- descriptors[group].bg_nfrees--;
-
- /* Clear bit to indicate that entry is free */
- mask = (uint32_t *)req->bp_bitmap->b_data;
- maskrw = mask[bitmap_idx];
- maskrw |= 1 << bitmap_off;
- mask[bitmap_idx] = maskrw;
-
- /* Make descriptor, bitmap and entry buffer dirty */
- if (nandfs_dirty_buf(req->bp_desc, 0) == 0) {
- nandfs_dirty_buf(req->bp_bitmap, 1);
- nandfs_dirty_buf(req->bp_entry, 1);
- } else {
- brelse(req->bp_bitmap);
- brelse(req->bp_entry);
- return (-1);
- }
-
- return (0);
-}
-
-void
-nandfs_abort_entry(struct nandfs_alloc_request *req)
-{
-
- brelse(req->bp_desc);
- brelse(req->bp_bitmap);
- brelse(req->bp_entry);
-}
-
-int
-nandfs_get_entry_block(struct nandfs_mdt *mdt, struct nandfs_node *node,
- struct nandfs_alloc_request *req, uint32_t *entry, int create)
-{
- struct buf *bp;
- nandfs_lbn_t blocknr;
- int error;
-
- /* Find buffer number for given entry */
- nandfs_mdt_trans(mdt, req->entrynum, &blocknr, entry);
- DPRINTF(ALLOC, ("%s: ino %#jx entrynum:%#jx block:%#jx entry:%x\n",
- __func__, (uintmax_t)node->nn_ino, (uintmax_t)req->entrynum,
- (uintmax_t)blocknr, *entry));
-
- /* Read entry block or create if 'create' parameter is not zero */
- bp = NULL;
-
- if (blocknr < node->nn_inode.i_blocks)
- error = nandfs_bread(node, blocknr, NOCRED, 0, &bp);
- else if (create)
- error = nandfs_bcreate(node, blocknr, NOCRED, 0, &bp);
- else
- error = E2BIG;
-
- if (error) {
- DPRINTF(ALLOC, ("%s: ino %#jx block %#jx entry %x error %d\n",
- __func__, (uintmax_t)node->nn_ino, (uintmax_t)blocknr,
- *entry, error));
- if (bp)
- brelse(bp);
- return (error);
- }
-
- MPASS(nandfs_vblk_get(bp) != 0 || node->nn_ino == NANDFS_DAT_INO);
-
- req->bp_entry = bp;
- return (0);
-}
diff --git a/sys/fs/nandfs/nandfs_bmap.c b/sys/fs/nandfs/nandfs_bmap.c
deleted file mode 100644
index 6a1c2b0775d5..000000000000
--- a/sys/fs/nandfs/nandfs_bmap.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/kernel.h>
-#include <sys/stat.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/signalvar.h>
-#include <sys/malloc.h>
-#include <sys/dirent.h>
-#include <sys/lockf.h>
-#include <sys/ktr.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-#include <vm/vnode_pager.h>
-
-#include <machine/_inttypes.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-#include <vm/vnode_pager.h>
-
-#include "nandfs_mount.h"
-#include "nandfs.h"
-#include "nandfs_subr.h"
-#include "bmap.h"
-
-nandfs_lbn_t
-nandfs_get_maxfilesize(struct nandfs_device *fsdev)
-{
-
- return (get_maxfilesize(fsdev));
-}
-
-int
-nandfs_bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk,
- nandfs_daddr_t *vblk)
-{
- int error = 0;
-
- if (node->nn_ino == NANDFS_GC_INO && lblk >= 0)
- *vblk = lblk;
- else
- error = bmap_lookup(node, lblk, vblk);
-
- DPRINTF(TRANSLATE, ("%s: error %d ino %#jx lblocknr %#jx -> %#jx\n",
- __func__, error, (uintmax_t)node->nn_ino, (uintmax_t)lblk,
- (uintmax_t)*vblk));
-
- if (error)
- nandfs_error("%s: returned %d", __func__, error);
-
- return (error);
-}
-
-int
-nandfs_bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk,
- struct buf *bp)
-{
- struct nandfs_device *fsdev;
- nandfs_daddr_t vblk;
- int error;
-
- fsdev = node->nn_nandfsdev;
-
- vblk = 0;
- if (node->nn_ino != NANDFS_DAT_INO) {
- error = nandfs_vblock_alloc(fsdev, &vblk);
- if (error)
- return (error);
- }
-
- nandfs_buf_set(bp, NANDFS_VBLK_ASSIGNED);
- nandfs_vblk_set(bp, vblk);
-
- error = bmap_insert_block(node, lblk, vblk);
- if (error) {
- nandfs_vblock_free(fsdev, vblk);
- return (error);
- }
-
- return (0);
-}
-
-int
-nandfs_bmap_dirty_blocks(struct nandfs_node *node, struct buf *bp, int force)
-{
- int error;
-
- error = bmap_dirty_meta(node, bp->b_lblkno, force);
- if (error)
- nandfs_error("%s: cannot dirty buffer %p\n",
- __func__, bp);
-
- return (error);
-}
-
-static int
-nandfs_bmap_update_mapping(struct nandfs_node *node, nandfs_lbn_t lblk,
- nandfs_daddr_t blknr)
-{
- int error;
-
- DPRINTF(BMAP,
- ("%s: node: %p ino: %#jx lblk: %#jx vblk: %#jx\n",
- __func__, node, (uintmax_t)node->nn_ino, (uintmax_t)lblk,
- (uintmax_t)blknr));
-
- error = bmap_insert_block(node, lblk, blknr);
-
- return (error);
-}
-
-int
-nandfs_bmap_update_block(struct nandfs_node *node, struct buf *bp,
- nandfs_lbn_t blknr)
-{
- nandfs_lbn_t lblk;
- int error;
-
- lblk = bp->b_lblkno;
- nandfs_vblk_set(bp, blknr);
-
- DPRINTF(BMAP, ("%s: node: %p ino: %#jx bp: %p lblk: %#jx blk: %#jx\n",
- __func__, node, (uintmax_t)node->nn_ino, bp,
- (uintmax_t)lblk, (uintmax_t)blknr));
-
- error = nandfs_bmap_update_mapping(node, lblk, blknr);
- if (error) {
- nandfs_error("%s: cannot update lblk:%jx to blk:%jx for "
- "node:%p, error:%d\n", __func__, (uintmax_t)lblk,
- (uintmax_t)blknr, node, error);
- return (error);
- }
-
- return (error);
-}
-
-int
-nandfs_bmap_update_dat(struct nandfs_node *node, nandfs_daddr_t oldblk,
- struct buf *bp)
-{
- struct nandfs_device *fsdev;
- nandfs_daddr_t vblk = 0;
- int error;
-
- if (node->nn_ino == NANDFS_DAT_INO)
- return (0);
-
- if (nandfs_buf_check(bp, NANDFS_VBLK_ASSIGNED)) {
- nandfs_buf_clear(bp, NANDFS_VBLK_ASSIGNED);
- return (0);
- }
-
- fsdev = node->nn_nandfsdev;
-
- /* First alloc new virtual block.... */
- error = nandfs_vblock_alloc(fsdev, &vblk);
- if (error)
- return (error);
-
- error = nandfs_bmap_update_block(node, bp, vblk);
- if (error)
- return (error);
-
- /* Then we can end up with old one */
- nandfs_vblock_end(fsdev, oldblk);
-
- DPRINTF(BMAP,
- ("%s: ino %#jx block %#jx: update vblk %#jx to %#jx\n",
- __func__, (uintmax_t)node->nn_ino, (uintmax_t)bp->b_lblkno,
- (uintmax_t)oldblk, (uintmax_t)vblk));
- return (error);
-}
-
-int
-nandfs_bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t oblk,
- nandfs_lbn_t nblk)
-{
- nandfs_lbn_t todo;
- int error;
-
- todo = oblk - nblk;
-
- DPRINTF(BMAP, ("%s: node %p oblk %jx nblk %jx truncate by %jx\n",
- __func__, node, oblk, nblk, todo));
-
- error = bmap_truncate_mapping(node, oblk, todo);
- if (error)
- return (error);
-
- return (error);
-}
diff --git a/sys/fs/nandfs/nandfs_buffer.c b/sys/fs/nandfs/nandfs_buffer.c
deleted file mode 100644
index 57089718554f..000000000000
--- a/sys/fs/nandfs/nandfs_buffer.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/buf.h>
-#include <sys/namei.h>
-#include <sys/vnode.h>
-#include <sys/bio.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-struct buf *
-nandfs_geteblk(int size, int flags)
-{
- struct buf *bp;
-
- /*
- * XXX
- * Right now we can call geteblk with GB_NOWAIT_BD flag, which means
- * it can return NULL. But we cannot afford to get NULL, hence this panic.
- */
- bp = geteblk(size, flags);
- if (bp == NULL)
- panic("geteblk returned NULL");
-
- return (bp);
-}
-
-void
-nandfs_dirty_bufs_increment(struct nandfs_device *fsdev)
-{
-
- mtx_lock(&fsdev->nd_mutex);
- KASSERT(fsdev->nd_dirty_bufs >= 0, ("negative nd_dirty_bufs"));
- fsdev->nd_dirty_bufs++;
- mtx_unlock(&fsdev->nd_mutex);
-}
-
-void
-nandfs_dirty_bufs_decrement(struct nandfs_device *fsdev)
-{
-
- mtx_lock(&fsdev->nd_mutex);
- KASSERT(fsdev->nd_dirty_bufs > 0,
- ("decrementing not-positive nd_dirty_bufs"));
- fsdev->nd_dirty_bufs--;
- mtx_unlock(&fsdev->nd_mutex);
-}
diff --git a/sys/fs/nandfs/nandfs_cleaner.c b/sys/fs/nandfs/nandfs_cleaner.c
deleted file mode 100644
index 3241c8701bfc..000000000000
--- a/sys/fs/nandfs/nandfs_cleaner.c
+++ /dev/null
@@ -1,622 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/buf.h>
-#include <sys/namei.h>
-#include <sys/vnode.h>
-#include <sys/bio.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-#define NANDFS_CLEANER_KILL 1
-
-static void nandfs_cleaner(struct nandfs_device *);
-static int nandfs_cleaner_clean_segments(struct nandfs_device *,
- struct nandfs_vinfo *, uint32_t, struct nandfs_period *, uint32_t,
- struct nandfs_bdesc *, uint32_t, uint64_t *, uint32_t);
-
-static int
-nandfs_process_bdesc(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd,
- uint64_t nmembs);
-
-static void
-nandfs_wakeup_wait_cleaner(struct nandfs_device *fsdev, int reason)
-{
-
- mtx_lock(&fsdev->nd_clean_mtx);
- if (reason == NANDFS_CLEANER_KILL)
- fsdev->nd_cleaner_exit = 1;
- if (fsdev->nd_cleaning == 0) {
- fsdev->nd_cleaning = 1;
- wakeup(&fsdev->nd_cleaning);
- }
- cv_wait(&fsdev->nd_clean_cv, &fsdev->nd_clean_mtx);
- mtx_unlock(&fsdev->nd_clean_mtx);
-}
-
-int
-nandfs_start_cleaner(struct nandfs_device *fsdev)
-{
- int error;
-
- MPASS(fsdev->nd_cleaner == NULL);
-
- fsdev->nd_cleaner_exit = 0;
-
- error = kthread_add((void(*)(void *))nandfs_cleaner, fsdev, NULL,
- &fsdev->nd_cleaner, 0, 0, "nandfs_cleaner");
- if (error)
- printf("nandfs: could not start cleaner: %d\n", error);
-
- return (error);
-}
-
-int
-nandfs_stop_cleaner(struct nandfs_device *fsdev)
-{
-
- MPASS(fsdev->nd_cleaner != NULL);
- nandfs_wakeup_wait_cleaner(fsdev, NANDFS_CLEANER_KILL);
- fsdev->nd_cleaner = NULL;
-
- DPRINTF(CLEAN, ("cleaner stopped\n"));
- return (0);
-}
-
-static int
-nandfs_cleaner_finished(struct nandfs_device *fsdev)
-{
- int exit;
-
- mtx_lock(&fsdev->nd_clean_mtx);
- fsdev->nd_cleaning = 0;
- if (!fsdev->nd_cleaner_exit) {
- DPRINTF(CLEAN, ("%s: sleep\n", __func__));
- msleep(&fsdev->nd_cleaning, &fsdev->nd_clean_mtx, PRIBIO, "-",
- hz * nandfs_cleaner_interval);
- }
- exit = fsdev->nd_cleaner_exit;
- cv_broadcast(&fsdev->nd_clean_cv);
- mtx_unlock(&fsdev->nd_clean_mtx);
- if (exit) {
- DPRINTF(CLEAN, ("%s: no longer active\n", __func__));
- return (1);
- }
-
- return (0);
-}
-
-static void
-print_suinfo(struct nandfs_suinfo *suinfo, int nsegs)
-{
- int i;
-
- for (i = 0; i < nsegs; i++) {
- DPRINTF(CLEAN, ("%jx %jd %c%c%c %10u\n",
- suinfo[i].nsi_num, suinfo[i].nsi_lastmod,
- (suinfo[i].nsi_flags &
- (NANDFS_SEGMENT_USAGE_ACTIVE) ? 'a' : '-'),
- (suinfo[i].nsi_flags &
- (NANDFS_SEGMENT_USAGE_DIRTY) ? 'd' : '-'),
- (suinfo[i].nsi_flags &
- (NANDFS_SEGMENT_USAGE_ERROR) ? 'e' : '-'),
- suinfo[i].nsi_blocks));
- }
-}
-
-static int
-nandfs_cleaner_vblock_is_alive(struct nandfs_device *fsdev,
- struct nandfs_vinfo *vinfo, struct nandfs_cpinfo *cp, uint32_t ncps)
-{
- int64_t idx, min, max;
-
- if (vinfo->nvi_end >= fsdev->nd_last_cno)
- return (1);
-
- if (ncps == 0)
- return (0);
-
- if (vinfo->nvi_end < cp[0].nci_cno ||
- vinfo->nvi_start > cp[ncps - 1].nci_cno)
- return (0);
-
- idx = min = 0;
- max = ncps - 1;
- while (min <= max) {
- idx = (min + max) / 2;
- if (vinfo->nvi_start == cp[idx].nci_cno)
- return (1);
- if (vinfo->nvi_start < cp[idx].nci_cno)
- max = idx - 1;
- else
- min = idx + 1;
- }
-
- return (vinfo->nvi_end >= cp[idx].nci_cno);
-}
-
-static void
-nandfs_cleaner_vinfo_mark_alive(struct nandfs_device *fsdev,
- struct nandfs_vinfo *vinfo, uint32_t nmembs, struct nandfs_cpinfo *cp,
- uint32_t ncps)
-{
- uint32_t i;
-
- for (i = 0; i < nmembs; i++)
- vinfo[i].nvi_alive =
- nandfs_cleaner_vblock_is_alive(fsdev, &vinfo[i], cp, ncps);
-}
-
-static int
-nandfs_cleaner_bdesc_is_alive(struct nandfs_device *fsdev,
- struct nandfs_bdesc *bdesc)
-{
- int alive;
-
- alive = bdesc->bd_oblocknr == bdesc->bd_blocknr;
- if (!alive)
- MPASS(abs(bdesc->bd_oblocknr - bdesc->bd_blocknr) > 2);
-
- return (alive);
-}
-
-static void
-nandfs_cleaner_bdesc_mark_alive(struct nandfs_device *fsdev,
- struct nandfs_bdesc *bdesc, uint32_t nmembs)
-{
- uint32_t i;
-
- for (i = 0; i < nmembs; i++)
- bdesc[i].bd_alive = nandfs_cleaner_bdesc_is_alive(fsdev,
- &bdesc[i]);
-}
-
-static void
-nandfs_cleaner_iterate_psegment(struct nandfs_device *fsdev,
- struct nandfs_segment_summary *segsum, union nandfs_binfo *binfo,
- nandfs_daddr_t blk, struct nandfs_vinfo **vipp, struct nandfs_bdesc **bdpp)
-{
- int i;
-
- DPRINTF(CLEAN, ("%s nbinfos %x\n", __func__, segsum->ss_nbinfos));
- for (i = 0; i < segsum->ss_nbinfos; i++) {
- if (binfo[i].bi_v.bi_ino == NANDFS_DAT_INO) {
- (*bdpp)->bd_oblocknr = blk + segsum->ss_nblocks -
- segsum->ss_nbinfos + i;
- /*
- * XXX Hack
- */
- if (segsum->ss_flags & NANDFS_SS_SR)
- (*bdpp)->bd_oblocknr--;
- (*bdpp)->bd_level = binfo[i].bi_dat.bi_level;
- (*bdpp)->bd_offset = binfo[i].bi_dat.bi_blkoff;
- (*bdpp)++;
- } else {
- (*vipp)->nvi_ino = binfo[i].bi_v.bi_ino;
- (*vipp)->nvi_vblocknr = binfo[i].bi_v.bi_vblocknr;
- (*vipp)++;
- }
- }
-}
-
-static int
-nandfs_cleaner_iterate_segment(struct nandfs_device *fsdev, uint64_t segno,
- struct nandfs_vinfo **vipp, struct nandfs_bdesc **bdpp, int *select)
-{
- struct nandfs_segment_summary *segsum;
- union nandfs_binfo *binfo;
- struct buf *bp;
- uint32_t nblocks;
- nandfs_daddr_t curr, start, end;
- int error = 0;
-
- nandfs_get_segment_range(fsdev, segno, &start, &end);
-
- DPRINTF(CLEAN, ("%s: segno %jx start %jx end %jx\n", __func__, segno,
- start, end));
-
- *select = 0;
-
- for (curr = start; curr < end; curr += nblocks) {
- error = nandfs_dev_bread(fsdev, curr, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- nandfs_error("%s: couldn't load segment summary of %jx: %d\n",
- __func__, segno, error);
- return (error);
- }
-
- segsum = (struct nandfs_segment_summary *)bp->b_data;
- binfo = (union nandfs_binfo *)(bp->b_data + segsum->ss_bytes);
-
- if (!nandfs_segsum_valid(segsum)) {
- brelse(bp);
- nandfs_error("nandfs: invalid summary of segment %jx\n", segno);
- return (error);
- }
-
- DPRINTF(CLEAN, ("%s: %jx magic %x bytes %x nblocks %x nbinfos "
- "%x\n", __func__, segno, segsum->ss_magic, segsum->ss_bytes,
- segsum->ss_nblocks, segsum->ss_nbinfos));
-
- nandfs_cleaner_iterate_psegment(fsdev, segsum, binfo, curr,
- vipp, bdpp);
- nblocks = segsum->ss_nblocks;
- brelse(bp);
- }
-
- if (error == 0)
- *select = 1;
-
- return (error);
-}
-
-static int
-nandfs_cleaner_choose_segment(struct nandfs_device *fsdev, uint64_t **segpp,
- uint64_t nsegs, uint64_t *rseg)
-{
- struct nandfs_suinfo *suinfo;
- uint64_t i, ssegs;
- int error;
-
- suinfo = malloc(sizeof(*suinfo) * nsegs, M_NANDFSTEMP,
- M_ZERO | M_WAITOK);
-
- if (*rseg >= fsdev->nd_fsdata.f_nsegments)
- *rseg = 0;
-
-retry:
- error = nandfs_get_segment_info_filter(fsdev, suinfo, nsegs, *rseg,
- &ssegs, NANDFS_SEGMENT_USAGE_DIRTY,
- NANDFS_SEGMENT_USAGE_ACTIVE | NANDFS_SEGMENT_USAGE_ERROR |
- NANDFS_SEGMENT_USAGE_GC);
- if (error) {
- nandfs_error("%s:%d", __FILE__, __LINE__);
- goto out;
- }
- if (ssegs == 0 && *rseg != 0) {
- *rseg = 0;
- goto retry;
- }
- if (ssegs > 0) {
- print_suinfo(suinfo, ssegs);
-
- for (i = 0; i < ssegs; i++) {
- (**segpp) = suinfo[i].nsi_num;
- (*segpp)++;
- }
- *rseg = suinfo[i - 1].nsi_num + 1;
- }
-
-out:
- free(suinfo, M_NANDFSTEMP);
- return (error);
-}
-
-static int
-nandfs_cleaner_body(struct nandfs_device *fsdev, uint64_t *rseg)
-{
- struct nandfs_vinfo *vinfo, *vip, *vipi;
- struct nandfs_bdesc *bdesc, *bdp, *bdpi;
- struct nandfs_cpstat cpstat;
- struct nandfs_cpinfo *cpinfo = NULL;
- uint64_t *segnums, *segp;
- int select, selected;
- int error = 0;
- int nsegs;
- int i;
-
- nsegs = nandfs_cleaner_segments;
-
- vip = vinfo = malloc(sizeof(*vinfo) *
- fsdev->nd_fsdata.f_blocks_per_segment * nsegs, M_NANDFSTEMP,
- M_ZERO | M_WAITOK);
- bdp = bdesc = malloc(sizeof(*bdesc) *
- fsdev->nd_fsdata.f_blocks_per_segment * nsegs, M_NANDFSTEMP,
- M_ZERO | M_WAITOK);
- segp = segnums = malloc(sizeof(*segnums) * nsegs, M_NANDFSTEMP,
- M_WAITOK);
-
- error = nandfs_cleaner_choose_segment(fsdev, &segp, nsegs, rseg);
- if (error) {
- nandfs_error("%s:%d", __FILE__, __LINE__);
- goto out;
- }
-
- if (segnums == segp)
- goto out;
-
- selected = 0;
- for (i = 0; i < segp - segnums; i++) {
- error = nandfs_cleaner_iterate_segment(fsdev, segnums[i], &vip,
- &bdp, &select);
- if (error) {
- /*
- * XXX deselect (see below)?
- */
- goto out;
- }
- if (!select)
- segnums[i] = NANDFS_NOSEGMENT;
- else {
- error = nandfs_markgc_segment(fsdev, segnums[i]);
- if (error) {
- nandfs_error("%s:%d\n", __FILE__, __LINE__);
- goto out;
- }
- selected++;
- }
- }
-
- if (selected == 0) {
- MPASS(vinfo == vip);
- MPASS(bdesc == bdp);
- goto out;
- }
-
- error = nandfs_get_cpstat(fsdev->nd_cp_node, &cpstat);
- if (error) {
- nandfs_error("%s:%d\n", __FILE__, __LINE__);
- goto out;
- }
-
- if (cpstat.ncp_nss != 0) {
- cpinfo = malloc(sizeof(struct nandfs_cpinfo) * cpstat.ncp_nss,
- M_NANDFSTEMP, M_WAITOK);
- error = nandfs_get_cpinfo(fsdev->nd_cp_node, 1, NANDFS_SNAPSHOT,
- cpinfo, cpstat.ncp_nss, NULL);
- if (error) {
- nandfs_error("%s:%d\n", __FILE__, __LINE__);
- goto out_locked;
- }
- }
-
- NANDFS_WRITELOCK(fsdev);
- DPRINTF(CLEAN, ("%s: got lock\n", __func__));
-
- error = nandfs_get_dat_vinfo(fsdev, vinfo, vip - vinfo);
- if (error) {
- nandfs_error("%s:%d\n", __FILE__, __LINE__);
- goto out_locked;
- }
-
- nandfs_cleaner_vinfo_mark_alive(fsdev, vinfo, vip - vinfo, cpinfo,
- cpstat.ncp_nss);
-
- error = nandfs_get_dat_bdescs(fsdev, bdesc, bdp - bdesc);
- if (error) {
- nandfs_error("%s:%d\n", __FILE__, __LINE__);
- goto out_locked;
- }
-
- nandfs_cleaner_bdesc_mark_alive(fsdev, bdesc, bdp - bdesc);
-
- DPRINTF(CLEAN, ("got:\n"));
- for (vipi = vinfo; vipi < vip; vipi++) {
- DPRINTF(CLEAN, ("v ino %jx vblocknr %jx start %jx end %jx "
- "alive %d\n", vipi->nvi_ino, vipi->nvi_vblocknr,
- vipi->nvi_start, vipi->nvi_end, vipi->nvi_alive));
- }
- for (bdpi = bdesc; bdpi < bdp; bdpi++) {
- DPRINTF(CLEAN, ("b oblocknr %jx blocknr %jx offset %jx "
- "alive %d\n", bdpi->bd_oblocknr, bdpi->bd_blocknr,
- bdpi->bd_offset, bdpi->bd_alive));
- }
- DPRINTF(CLEAN, ("end list\n"));
-
- error = nandfs_cleaner_clean_segments(fsdev, vinfo, vip - vinfo, NULL,
- 0, bdesc, bdp - bdesc, segnums, segp - segnums);
- if (error)
- nandfs_error("%s:%d\n", __FILE__, __LINE__);
-
-out_locked:
- NANDFS_WRITEUNLOCK(fsdev);
-out:
- free(cpinfo, M_NANDFSTEMP);
- free(segnums, M_NANDFSTEMP);
- free(bdesc, M_NANDFSTEMP);
- free(vinfo, M_NANDFSTEMP);
-
- return (error);
-}
-
-static void
-nandfs_cleaner(struct nandfs_device *fsdev)
-{
- uint64_t checked_seg = 0;
- int error;
-
- while (!nandfs_cleaner_finished(fsdev)) {
- if (!nandfs_cleaner_enable || rebooting)
- continue;
-
- DPRINTF(CLEAN, ("%s: run started\n", __func__));
-
- fsdev->nd_cleaning = 1;
-
- error = nandfs_cleaner_body(fsdev, &checked_seg);
-
- DPRINTF(CLEAN, ("%s: run finished error %d\n", __func__,
- error));
- }
-
- DPRINTF(CLEAN, ("%s: exiting\n", __func__));
- kthread_exit();
-}
-
-static int
-nandfs_cleaner_clean_segments(struct nandfs_device *nffsdev,
- struct nandfs_vinfo *vinfo, uint32_t nvinfo,
- struct nandfs_period *pd, uint32_t npd,
- struct nandfs_bdesc *bdesc, uint32_t nbdesc,
- uint64_t *segments, uint32_t nsegs)
-{
- struct nandfs_node *gc;
- struct buf *bp;
- uint32_t i;
- int error = 0;
-
- gc = nffsdev->nd_gc_node;
-
- DPRINTF(CLEAN, ("%s: enter\n", __func__));
-
- VOP_LOCK(NTOV(gc), LK_EXCLUSIVE);
- for (i = 0; i < nvinfo; i++) {
- if (!vinfo[i].nvi_alive)
- continue;
- DPRINTF(CLEAN, ("%s: read vblknr:%#jx blk:%#jx\n",
- __func__, (uintmax_t)vinfo[i].nvi_vblocknr,
- (uintmax_t)vinfo[i].nvi_blocknr));
- error = nandfs_bread(nffsdev->nd_gc_node, vinfo[i].nvi_blocknr,
- NULL, 0, &bp);
- if (error) {
- nandfs_error("%s:%d", __FILE__, __LINE__);
- VOP_UNLOCK(NTOV(gc), 0);
- goto out;
- }
- nandfs_vblk_set(bp, vinfo[i].nvi_vblocknr);
- nandfs_buf_set(bp, NANDFS_VBLK_ASSIGNED);
- nandfs_dirty_buf(bp, 1);
- }
- VOP_UNLOCK(NTOV(gc), 0);
-
- /* Delete checkpoints */
- for (i = 0; i < npd; i++) {
- DPRINTF(CLEAN, ("delete checkpoint: %jx\n",
- (uintmax_t)pd[i].p_start));
- error = nandfs_delete_cp(nffsdev->nd_cp_node, pd[i].p_start,
- pd[i].p_end);
- if (error) {
- nandfs_error("%s:%d", __FILE__, __LINE__);
- goto out;
- }
- }
-
- /* Update vblocks */
- for (i = 0; i < nvinfo; i++) {
- if (vinfo[i].nvi_alive)
- continue;
- DPRINTF(CLEAN, ("freeing vblknr: %jx\n", vinfo[i].nvi_vblocknr));
- error = nandfs_vblock_free(nffsdev, vinfo[i].nvi_vblocknr);
- if (error) {
- nandfs_error("%s:%d", __FILE__, __LINE__);
- goto out;
- }
- }
-
- error = nandfs_process_bdesc(nffsdev, bdesc, nbdesc);
- if (error) {
- nandfs_error("%s:%d", __FILE__, __LINE__);
- goto out;
- }
-
- /* Add segments to clean */
- if (nffsdev->nd_free_count) {
- nffsdev->nd_free_base = realloc(nffsdev->nd_free_base,
- (nffsdev->nd_free_count + nsegs) * sizeof(uint64_t),
- M_NANDFSTEMP, M_WAITOK | M_ZERO);
- memcpy(&nffsdev->nd_free_base[nffsdev->nd_free_count], segments,
- nsegs * sizeof(uint64_t));
- nffsdev->nd_free_count += nsegs;
- } else {
- nffsdev->nd_free_base = malloc(nsegs * sizeof(uint64_t),
- M_NANDFSTEMP, M_WAITOK|M_ZERO);
- memcpy(nffsdev->nd_free_base, segments,
- nsegs * sizeof(uint64_t));
- nffsdev->nd_free_count = nsegs;
- }
-
-out:
-
- DPRINTF(CLEAN, ("%s: exit error %d\n", __func__, error));
-
- return (error);
-}
-
-static int
-nandfs_process_bdesc(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd,
- uint64_t nmembs)
-{
- struct nandfs_node *dat_node;
- struct buf *bp;
- uint64_t i;
- int error;
-
- dat_node = nffsdev->nd_dat_node;
-
- VOP_LOCK(NTOV(dat_node), LK_EXCLUSIVE);
-
- for (i = 0; i < nmembs; i++) {
- if (!bd[i].bd_alive)
- continue;
- DPRINTF(CLEAN, ("%s: idx %jx offset %jx\n",
- __func__, i, bd[i].bd_offset));
- if (bd[i].bd_level) {
- error = nandfs_bread_meta(dat_node, bd[i].bd_offset,
- NULL, 0, &bp);
- if (error) {
- nandfs_error("%s: cannot read dat node "
- "level:%d\n", __func__, bd[i].bd_level);
- brelse(bp);
- VOP_UNLOCK(NTOV(dat_node), 0);
- return (error);
- }
- nandfs_dirty_buf_meta(bp, 1);
- nandfs_bmap_dirty_blocks(VTON(bp->b_vp), bp, 1);
- } else {
- error = nandfs_bread(dat_node, bd[i].bd_offset, NULL,
- 0, &bp);
- if (error) {
- nandfs_error("%s: cannot read dat node\n",
- __func__);
- brelse(bp);
- VOP_UNLOCK(NTOV(dat_node), 0);
- return (error);
- }
- nandfs_dirty_buf(bp, 1);
- }
- DPRINTF(CLEAN, ("%s: bp: %p\n", __func__, bp));
- }
-
- VOP_UNLOCK(NTOV(dat_node), 0);
-
- return (0);
-}
diff --git a/sys/fs/nandfs/nandfs_cpfile.c b/sys/fs/nandfs/nandfs_cpfile.c
deleted file mode 100644
index 8c9a695879e4..000000000000
--- a/sys/fs/nandfs/nandfs_cpfile.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/sysctl.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include "nandfs_mount.h"
-#include "nandfs.h"
-#include "nandfs_subr.h"
-
-
-static int
-nandfs_checkpoint_size(struct nandfs_device *fsdev)
-{
-
- return (fsdev->nd_fsdata.f_checkpoint_size);
-}
-
-static int
-nandfs_checkpoint_blk_offset(struct nandfs_device *fsdev, uint64_t cn,
- uint64_t *blk, uint64_t *offset)
-{
- uint64_t off;
- uint16_t cp_size, cp_per_blk;
-
- KASSERT((cn), ("checkpoing cannot be zero"));
-
- cp_size = fsdev->nd_fsdata.f_checkpoint_size;
- cp_per_blk = fsdev->nd_blocksize / cp_size;
- off = roundup(sizeof(struct nandfs_cpfile_header), cp_size) / cp_size;
- off += (cn - 1);
-
- *blk = off / cp_per_blk;
- *offset = (off % cp_per_blk) * cp_size;
-
- return (0);
-}
-
-static int
-nandfs_checkpoint_blk_remaining(struct nandfs_device *fsdev, uint64_t cn,
- uint64_t blk, uint64_t offset)
-{
- uint16_t cp_size, cp_remaining;
-
- cp_size = fsdev->nd_fsdata.f_checkpoint_size;
- cp_remaining = (fsdev->nd_blocksize - offset) / cp_size;
-
- return (cp_remaining);
-}
-
-int
-nandfs_get_checkpoint(struct nandfs_device *fsdev, struct nandfs_node *cp_node,
- uint64_t cn)
-{
- struct buf *bp;
- uint64_t blk, offset;
- int error;
-
- if (cn != fsdev->nd_last_cno && cn != (fsdev->nd_last_cno + 1)) {
- return (-1);
- }
-
- error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (-1);
- }
-
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (-1);
-
-
- nandfs_checkpoint_blk_offset(fsdev, cn, &blk, &offset);
-
- if (blk != 0) {
- if (blk < cp_node->nn_inode.i_blocks)
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- else
- error = nandfs_bcreate(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- if (bp)
- brelse(bp);
- return (-1);
- }
-
- nandfs_dirty_buf(bp, 1);
- }
-
- DPRINTF(CPFILE, ("%s: cn:%#jx entry block:%#jx offset:%#jx\n",
- __func__, (uintmax_t)cn, (uintmax_t)blk, (uintmax_t)offset));
-
- return (0);
-}
-
-int
-nandfs_set_checkpoint(struct nandfs_device *fsdev, struct nandfs_node *cp_node,
- uint64_t cn, struct nandfs_inode *ifile_inode, uint64_t nblocks)
-{
- struct nandfs_cpfile_header *cnh;
- struct nandfs_checkpoint *cnp;
- struct buf *bp;
- uint64_t blk, offset;
- int error;
-
- if (cn != fsdev->nd_last_cno && cn != (fsdev->nd_last_cno + 1)) {
- nandfs_error("%s: trying to set invalid chekpoint %jx - %jx\n",
- __func__, cn, fsdev->nd_last_cno);
- return (-1);
- }
-
- error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return error;
- }
-
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- cnh->ch_ncheckpoints++;
-
- nandfs_checkpoint_blk_offset(fsdev, cn, &blk, &offset);
-
- if(blk != 0) {
- brelse(bp);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return error;
- }
- }
-
- cnp = (struct nandfs_checkpoint *)((uint8_t *)bp->b_data + offset);
- cnp->cp_flags = 0;
- cnp->cp_checkpoints_count = 1;
- memset(&cnp->cp_snapshot_list, 0, sizeof(struct nandfs_snapshot_list));
- cnp->cp_cno = cn;
- cnp->cp_create = fsdev->nd_ts.tv_sec;
- cnp->cp_nblk_inc = nblocks;
- cnp->cp_blocks_count = 0;
- memcpy (&cnp->cp_ifile_inode, ifile_inode, sizeof(cnp->cp_ifile_inode));
-
- DPRINTF(CPFILE, ("%s: cn:%#jx ctime:%#jx nblk:%#jx\n",
- __func__, (uintmax_t)cn, (uintmax_t)cnp->cp_create,
- (uintmax_t)nblocks));
-
- brelse(bp);
- return (0);
-}
-
-static int
-nandfs_cp_mounted(struct nandfs_device *nandfsdev, uint64_t cno)
-{
- struct nandfsmount *nmp;
- int mounted = 0;
-
- mtx_lock(&nandfsdev->nd_mutex);
- /* No double-mounting of the same checkpoint */
- STAILQ_FOREACH(nmp, &nandfsdev->nd_mounts, nm_next_mount) {
- if (nmp->nm_mount_args.cpno == cno) {
- mounted = 1;
- break;
- }
- }
- mtx_unlock(&nandfsdev->nd_mutex);
-
- return (mounted);
-}
-
-static int
-nandfs_cp_set_snapshot(struct nandfs_node *cp_node, uint64_t cno)
-{
- struct nandfs_device *fsdev;
- struct nandfs_cpfile_header *cnh;
- struct nandfs_checkpoint *cnp;
- struct nandfs_snapshot_list *list;
- struct buf *bp;
- uint64_t blk, prev_blk, offset;
- uint64_t curr, prev;
- int error;
-
- fsdev = cp_node->nn_nandfsdev;
-
- /* Get snapshot data */
- nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- if (cnp->cp_flags & NANDFS_CHECKPOINT_INVALID) {
- brelse(bp);
- return (ENOENT);
- }
- if ((cnp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT)) {
- brelse(bp);
- return (EINVAL);
- }
-
- brelse(bp);
- /* Get list from header */
- error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- list = &cnh->ch_snapshot_list;
- prev = list->ssl_prev;
- brelse(bp);
- prev_blk = ~(0);
- curr = 0;
- while (prev > cno) {
- curr = prev;
- nandfs_checkpoint_blk_offset(fsdev, prev, &prev_blk, &offset);
- error = nandfs_bread(cp_node, prev_blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- list = &cnp->cp_snapshot_list;
- prev = list->ssl_prev;
- brelse(bp);
- }
-
- if (curr == 0) {
- nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- list = &cnh->ch_snapshot_list;
- } else {
- nandfs_checkpoint_blk_offset(fsdev, curr, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- list = &cnp->cp_snapshot_list;
- }
-
- list->ssl_prev = cno;
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (error);
-
-
- /* Update snapshot for cno */
- nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- list = &cnp->cp_snapshot_list;
- list->ssl_prev = prev;
- list->ssl_next = curr;
- cnp->cp_flags |= NANDFS_CHECKPOINT_SNAPSHOT;
- nandfs_dirty_buf(bp, 1);
-
- if (prev == 0) {
- nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- list = &cnh->ch_snapshot_list;
- } else {
- /* Update snapshot list for prev */
- nandfs_checkpoint_blk_offset(fsdev, prev, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- list = &cnp->cp_snapshot_list;
- }
- list->ssl_next = cno;
- nandfs_dirty_buf(bp, 1);
-
- /* Update header */
- error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- cnh->ch_nsnapshots++;
- nandfs_dirty_buf(bp, 1);
-
- return (0);
-}
-
-static int
-nandfs_cp_clr_snapshot(struct nandfs_node *cp_node, uint64_t cno)
-{
- struct nandfs_device *fsdev;
- struct nandfs_cpfile_header *cnh;
- struct nandfs_checkpoint *cnp;
- struct nandfs_snapshot_list *list;
- struct buf *bp;
- uint64_t blk, offset, snapshot_cnt;
- uint64_t next, prev;
- int error;
-
- fsdev = cp_node->nn_nandfsdev;
-
- /* Get snapshot data */
- nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- if (cnp->cp_flags & NANDFS_CHECKPOINT_INVALID) {
- brelse(bp);
- return (ENOENT);
- }
- if (!(cnp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT)) {
- brelse(bp);
- return (EINVAL);
- }
-
- list = &cnp->cp_snapshot_list;
- next = list->ssl_next;
- prev = list->ssl_prev;
- brelse(bp);
-
- /* Get previous snapshot */
- if (prev != 0) {
- nandfs_checkpoint_blk_offset(fsdev, prev, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- list = &cnp->cp_snapshot_list;
- } else {
- nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- list = &cnh->ch_snapshot_list;
- }
-
- list->ssl_next = next;
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (error);
-
- /* Get next snapshot */
- if (next != 0) {
- nandfs_checkpoint_blk_offset(fsdev, next, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- list = &cnp->cp_snapshot_list;
- } else {
- nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- list = &cnh->ch_snapshot_list;
- }
- list->ssl_prev = prev;
- nandfs_dirty_buf(bp, 1);
-
- /* Update snapshot list for cno */
- nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset);
- error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- list = &cnp->cp_snapshot_list;
- list->ssl_prev = 0;
- list->ssl_next = 0;
- cnp->cp_flags &= !NANDFS_CHECKPOINT_SNAPSHOT;
- nandfs_dirty_buf(bp, 1);
-
- /* Update header */
- error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- snapshot_cnt = cnh->ch_nsnapshots;
- snapshot_cnt--;
- cnh->ch_nsnapshots = snapshot_cnt;
- nandfs_dirty_buf(bp, 1);
-
- return (0);
-}
-
-int
-nandfs_chng_cpmode(struct nandfs_node *node, struct nandfs_cpmode *ncpm)
-{
- struct nandfs_device *fsdev;
- uint64_t cno = ncpm->ncpm_cno;
- int mode = ncpm->ncpm_mode;
- int ret;
-
- fsdev = node->nn_nandfsdev;
- VOP_LOCK(NTOV(node), LK_EXCLUSIVE);
- switch (mode) {
- case NANDFS_CHECKPOINT:
- if (nandfs_cp_mounted(fsdev, cno)) {
- ret = EBUSY;
- } else
- ret = nandfs_cp_clr_snapshot(node, cno);
- break;
- case NANDFS_SNAPSHOT:
- ret = nandfs_cp_set_snapshot(node, cno);
- break;
- default:
- ret = EINVAL;
- break;
- }
- VOP_UNLOCK(NTOV(node), 0);
-
- return (ret);
-}
-
-static void
-nandfs_cpinfo_fill(struct nandfs_checkpoint *cnp, struct nandfs_cpinfo *nci)
-{
-
- nci->nci_flags = cnp->cp_flags;
- nci->nci_pad = 0;
- nci->nci_cno = cnp->cp_cno;
- nci->nci_create = cnp->cp_create;
- nci->nci_nblk_inc = cnp->cp_nblk_inc;
- nci->nci_blocks_count = cnp->cp_blocks_count;
- nci->nci_next = cnp->cp_snapshot_list.ssl_next;
- DPRINTF(CPFILE, ("%s: cn:%#jx ctime:%#jx\n",
- __func__, (uintmax_t)cnp->cp_cno,
- (uintmax_t)cnp->cp_create));
-}
-
-static int
-nandfs_get_cpinfo_cp(struct nandfs_node *node, uint64_t cno,
- struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs)
-{
- struct nandfs_device *fsdev;
- struct buf *bp;
- uint64_t blk, offset, last_cno, i;
- uint16_t remaining;
- int error;
-#ifdef INVARIANTS
- uint64_t testblk, testoffset;
-#endif
-
- if (cno == 0) {
- return (ENOENT);
- }
-
- if (mnmembs < 1) {
- return (EINVAL);
- }
-
- fsdev = node->nn_nandfsdev;
- last_cno = fsdev->nd_last_cno;
- DPRINTF(CPFILE, ("%s: cno:%#jx mnmembs: %#jx last:%#jx\n", __func__,
- (uintmax_t)cno, (uintmax_t)mnmembs,
- (uintmax_t)fsdev->nd_last_cno));
-
- /*
- * do {
- * get block
- * read checkpoints until we hit last checkpoint, end of block or
- * requested number
- * } while (last read checkpoint <= last checkpoint on fs &&
- * read checkpoints < request number);
- */
- *nmembs = i = 0;
- do {
- nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset);
- remaining = nandfs_checkpoint_blk_remaining(fsdev, cno,
- blk, offset);
- error = nandfs_bread(node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- while (cno <= last_cno && i < mnmembs && remaining) {
-#ifdef INVARIANTS
- nandfs_checkpoint_blk_offset(fsdev, cno, &testblk,
- &testoffset);
- KASSERT(testblk == blk, ("testblk != blk"));
- KASSERT(testoffset == offset, ("testoffset != offset"));
-#endif
- DPRINTF(CPFILE, ("%s: cno %#jx\n", __func__,
- (uintmax_t)cno));
-
- nandfs_cpinfo_fill((struct nandfs_checkpoint *)
- (bp->b_data + offset), nci);
- offset += nandfs_checkpoint_size(fsdev);
- i++;
- nci++;
- cno++;
- (*nmembs)++;
- remaining--;
- }
- brelse(bp);
- } while (cno <= last_cno && i < mnmembs);
-
- return (0);
-}
-
-static int
-nandfs_get_cpinfo_sp(struct nandfs_node *node, uint64_t cno,
- struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs)
-{
- struct nandfs_checkpoint *cnp;
- struct nandfs_cpfile_header *cnh;
- struct nandfs_device *fsdev;
- struct buf *bp = NULL;
- uint64_t curr = 0;
- uint64_t blk, offset, curr_cno;
- uint32_t flag;
- int i, error;
-
- if (cno == 0 || cno == ~(0))
- return (ENOENT);
-
- fsdev = node->nn_nandfsdev;
- curr_cno = cno;
-
- if (nmembs)
- *nmembs = 0;
- if (curr_cno == 1) {
- /* Get list from header */
- error = nandfs_bread(node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- curr_cno = cnh->ch_snapshot_list.ssl_next;
- brelse(bp);
- bp = NULL;
-
- /* No snapshots */
- if (curr_cno == 0)
- return (0);
- }
-
- for (i = 0; i < mnmembs; i++, nci++) {
- nandfs_checkpoint_blk_offset(fsdev, curr_cno, &blk, &offset);
- if (i == 0 || curr != blk) {
- if (bp)
- brelse(bp);
- error = nandfs_bread(node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (ENOENT);
- }
- curr = blk;
- }
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- flag = cnp->cp_flags;
- if (!(flag & NANDFS_CHECKPOINT_SNAPSHOT) ||
- (flag & NANDFS_CHECKPOINT_INVALID))
- break;
-
- nci->nci_flags = flag;
- nci->nci_pad = 0;
- nci->nci_cno = cnp->cp_cno;
- nci->nci_create = cnp->cp_create;
- nci->nci_nblk_inc = cnp->cp_nblk_inc;
- nci->nci_blocks_count = cnp->cp_blocks_count;
- nci->nci_next = cnp->cp_snapshot_list.ssl_next;
- if (nmembs)
- (*nmembs)++;
-
- curr_cno = nci->nci_next;
- if (!curr_cno)
- break;
- }
-
- brelse(bp);
-
- return (0);
-}
-
-int
-nandfs_get_cpinfo(struct nandfs_node *node, uint64_t cno, uint16_t flags,
- struct nandfs_cpinfo *nci, uint32_t nmembs, uint32_t *nnmembs)
-{
- int error;
-
- VOP_LOCK(NTOV(node), LK_EXCLUSIVE);
- switch (flags) {
- case NANDFS_CHECKPOINT:
- error = nandfs_get_cpinfo_cp(node, cno, nci, nmembs, nnmembs);
- break;
- case NANDFS_SNAPSHOT:
- error = nandfs_get_cpinfo_sp(node, cno, nci, nmembs, nnmembs);
- break;
- default:
- error = EINVAL;
- break;
- }
- VOP_UNLOCK(NTOV(node), 0);
-
- return (error);
-}
-
-int
-nandfs_get_cpinfo_ioctl(struct nandfs_node *node, struct nandfs_argv *nargv)
-{
- struct nandfs_cpinfo *nci;
- uint64_t cno = nargv->nv_index;
- void *buf = (void *)((uintptr_t)nargv->nv_base);
- uint16_t flags = nargv->nv_flags;
- uint32_t nmembs = 0;
- int error;
-
- if (nargv->nv_nmembs > NANDFS_CPINFO_MAX)
- return (EINVAL);
-
- nci = malloc(sizeof(struct nandfs_cpinfo) * nargv->nv_nmembs,
- M_NANDFSTEMP, M_WAITOK | M_ZERO);
-
- error = nandfs_get_cpinfo(node, cno, flags, nci, nargv->nv_nmembs, &nmembs);
-
- if (error == 0) {
- nargv->nv_nmembs = nmembs;
- error = copyout(nci, buf,
- sizeof(struct nandfs_cpinfo) * nmembs);
- }
-
- free(nci, M_NANDFSTEMP);
- return (error);
-}
-
-int
-nandfs_delete_cp(struct nandfs_node *node, uint64_t start, uint64_t end)
-{
- struct nandfs_checkpoint *cnp;
- struct nandfs_device *fsdev;
- struct buf *bp;
- uint64_t cno = start, blk, offset;
- int error;
-
- DPRINTF(CPFILE, ("%s: delete cno %jx-%jx\n", __func__, start, end));
- VOP_LOCK(NTOV(node), LK_EXCLUSIVE);
- fsdev = node->nn_nandfsdev;
- for (cno = start; cno <= end; cno++) {
- if (!cno)
- continue;
-
- nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset);
- error = nandfs_bread(node, blk, NOCRED, 0, &bp);
- if (error) {
- VOP_UNLOCK(NTOV(node), 0);
- brelse(bp);
- return (error);
- }
-
- cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
- if (cnp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT) {
- brelse(bp);
- VOP_UNLOCK(NTOV(node), 0);
- return (0);
- }
-
- cnp->cp_flags |= NANDFS_CHECKPOINT_INVALID;
-
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (error);
- }
- VOP_UNLOCK(NTOV(node), 0);
-
- return (0);
-}
-
-int
-nandfs_make_snap(struct nandfs_device *fsdev, uint64_t *cno)
-{
- struct nandfs_cpmode cpm;
- int error;
-
- *cno = cpm.ncpm_cno = fsdev->nd_last_cno;
- cpm.ncpm_mode = NANDFS_SNAPSHOT;
- error = nandfs_chng_cpmode(fsdev->nd_cp_node, &cpm);
- return (error);
-}
-
-int
-nandfs_delete_snap(struct nandfs_device *fsdev, uint64_t cno)
-{
- struct nandfs_cpmode cpm;
- int error;
-
- cpm.ncpm_cno = cno;
- cpm.ncpm_mode = NANDFS_CHECKPOINT;
- error = nandfs_chng_cpmode(fsdev->nd_cp_node, &cpm);
- return (error);
-}
-
-int nandfs_get_cpstat(struct nandfs_node *cp_node, struct nandfs_cpstat *ncp)
-{
- struct nandfs_device *fsdev;
- struct nandfs_cpfile_header *cnh;
- struct buf *bp;
- int error;
-
- VOP_LOCK(NTOV(cp_node), LK_EXCLUSIVE);
- fsdev = cp_node->nn_nandfsdev;
-
- /* Get header */
- error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- VOP_UNLOCK(NTOV(cp_node), 0);
- return (error);
- }
- cnh = (struct nandfs_cpfile_header *) bp->b_data;
- ncp->ncp_cno = fsdev->nd_last_cno;
- ncp->ncp_ncps = cnh->ch_ncheckpoints;
- ncp->ncp_nss = cnh->ch_nsnapshots;
- DPRINTF(CPFILE, ("%s: cno:%#jx ncps:%#jx nss:%#jx\n",
- __func__, ncp->ncp_cno, ncp->ncp_ncps, ncp->ncp_nss));
- brelse(bp);
- VOP_UNLOCK(NTOV(cp_node), 0);
-
- return (0);
-}
diff --git a/sys/fs/nandfs/nandfs_dat.c b/sys/fs/nandfs/nandfs_dat.c
deleted file mode 100644
index e81a117589f8..000000000000
--- a/sys/fs/nandfs/nandfs_dat.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/sysctl.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-int
-nandfs_vblock_alloc(struct nandfs_device *nandfsdev, nandfs_daddr_t *vblock)
-{
- struct nandfs_node *dat;
- struct nandfs_mdt *mdt;
- struct nandfs_alloc_request req;
- struct nandfs_dat_entry *dat_entry;
- uint64_t start;
- uint32_t entry;
- int locked, error;
-
- dat = nandfsdev->nd_dat_node;
- mdt = &nandfsdev->nd_dat_mdt;
- start = nandfsdev->nd_last_cno + 1;
-
- locked = NANDFS_VOP_ISLOCKED(NTOV(dat));
- if (!locked)
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- req.entrynum = 0;
-
- /* Alloc vblock number */
- error = nandfs_find_free_entry(mdt, dat, &req);
- if (error) {
- nandfs_error("%s: cannot find free vblk entry\n",
- __func__);
- if (!locked)
- VOP_UNLOCK(NTOV(dat), 0);
- return (error);
- }
-
- /* Read/create buffer */
- error = nandfs_get_entry_block(mdt, dat, &req, &entry, 1);
- if (error) {
- nandfs_error("%s: cannot get free vblk entry\n",
- __func__);
- nandfs_abort_entry(&req);
- if (!locked)
- VOP_UNLOCK(NTOV(dat), 0);
- return (error);
- }
-
- /* Fill out vblock data */
- dat_entry = (struct nandfs_dat_entry *) req.bp_entry->b_data;
- dat_entry[entry].de_start = start;
- dat_entry[entry].de_end = UINTMAX_MAX;
- dat_entry[entry].de_blocknr = 0;
-
- /* Commit allocation */
- error = nandfs_alloc_entry(mdt, &req);
- if (error) {
- nandfs_error("%s: cannot get free vblk entry\n",
- __func__);
- if (!locked)
- VOP_UNLOCK(NTOV(dat), 0);
- return (error);
- }
-
- /* Return allocated vblock */
- *vblock = req.entrynum;
- DPRINTF(DAT, ("%s: allocated vblock %#jx\n",
- __func__, (uintmax_t)*vblock));
-
- if (!locked)
- VOP_UNLOCK(NTOV(dat), 0);
- return (error);
-}
-
-int
-nandfs_vblock_assign(struct nandfs_device *nandfsdev, nandfs_daddr_t vblock,
- nandfs_lbn_t block)
-{
- struct nandfs_node *dat;
- struct nandfs_mdt *mdt;
- struct nandfs_alloc_request req;
- struct nandfs_dat_entry *dat_entry;
- uint32_t entry;
- int locked, error;
-
- dat = nandfsdev->nd_dat_node;
- mdt = &nandfsdev->nd_dat_mdt;
-
- locked = NANDFS_VOP_ISLOCKED(NTOV(dat));
- if (!locked)
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- req.entrynum = vblock;
-
- error = nandfs_get_entry_block(mdt, dat, &req, &entry, 0);
- if (!error) {
- dat_entry = (struct nandfs_dat_entry *) req.bp_entry->b_data;
- dat_entry[entry].de_blocknr = block;
-
- DPRINTF(DAT, ("%s: assing vblock %jx->%jx\n",
- __func__, (uintmax_t)vblock, (uintmax_t)block));
-
- /*
- * It is mostly called from syncer() so
- * we want to force making buf dirty
- */
- error = nandfs_dirty_buf(req.bp_entry, 1);
- }
-
- if (!locked)
- VOP_UNLOCK(NTOV(dat), 0);
-
- return (error);
-}
-
-int
-nandfs_vblock_end(struct nandfs_device *nandfsdev, nandfs_daddr_t vblock)
-{
- struct nandfs_node *dat;
- struct nandfs_mdt *mdt;
- struct nandfs_alloc_request req;
- struct nandfs_dat_entry *dat_entry;
- uint64_t end;
- uint32_t entry;
- int locked, error;
-
- dat = nandfsdev->nd_dat_node;
- mdt = &nandfsdev->nd_dat_mdt;
- end = nandfsdev->nd_last_cno;
-
- locked = NANDFS_VOP_ISLOCKED(NTOV(dat));
- if (!locked)
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- req.entrynum = vblock;
-
- error = nandfs_get_entry_block(mdt, dat, &req, &entry, 0);
- if (!error) {
- dat_entry = (struct nandfs_dat_entry *) req.bp_entry->b_data;
- dat_entry[entry].de_end = end;
- DPRINTF(DAT, ("%s: end vblock %#jx at checkpoint %#jx\n",
- __func__, (uintmax_t)vblock, (uintmax_t)end));
-
- /*
- * It is mostly called from syncer() so
- * we want to force making buf dirty
- */
- error = nandfs_dirty_buf(req.bp_entry, 1);
- }
-
- if (!locked)
- VOP_UNLOCK(NTOV(dat), 0);
-
- return (error);
-}
-
-int
-nandfs_vblock_free(struct nandfs_device *nandfsdev, nandfs_daddr_t vblock)
-{
- struct nandfs_node *dat;
- struct nandfs_mdt *mdt;
- struct nandfs_alloc_request req;
- int error;
-
- dat = nandfsdev->nd_dat_node;
- mdt = &nandfsdev->nd_dat_mdt;
-
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- req.entrynum = vblock;
-
- error = nandfs_find_entry(mdt, dat, &req);
- if (!error) {
- DPRINTF(DAT, ("%s: vblk %#jx\n", __func__, (uintmax_t)vblock));
- nandfs_free_entry(mdt, &req);
- }
-
- VOP_UNLOCK(NTOV(dat), 0);
- return (error);
-}
-
-int
-nandfs_get_dat_vinfo_ioctl(struct nandfs_device *nandfsdev, struct nandfs_argv *nargv)
-{
- struct nandfs_vinfo *vinfo;
- size_t size;
- int error;
-
- if (nargv->nv_nmembs > NANDFS_VINFO_MAX)
- return (EINVAL);
-
- size = sizeof(struct nandfs_vinfo) * nargv->nv_nmembs;
- vinfo = malloc(size, M_NANDFSTEMP, M_WAITOK|M_ZERO);
-
- error = copyin((void *)(uintptr_t)nargv->nv_base, vinfo, size);
- if (error) {
- free(vinfo, M_NANDFSTEMP);
- return (error);
- }
-
- error = nandfs_get_dat_vinfo(nandfsdev, vinfo, nargv->nv_nmembs);
- if (error == 0)
- error = copyout(vinfo, (void *)(uintptr_t)nargv->nv_base, size);
- free(vinfo, M_NANDFSTEMP);
- return (error);
-}
-
-int
-nandfs_get_dat_vinfo(struct nandfs_device *nandfsdev, struct nandfs_vinfo *vinfo,
- uint32_t nmembs)
-{
- struct nandfs_node *dat;
- struct nandfs_mdt *mdt;
- struct nandfs_alloc_request req;
- struct nandfs_dat_entry *dat_entry;
- uint32_t i, idx;
- int error = 0;
-
- dat = nandfsdev->nd_dat_node;
- mdt = &nandfsdev->nd_dat_mdt;
-
- DPRINTF(DAT, ("%s: nmembs %#x\n", __func__, nmembs));
-
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
-
- for (i = 0; i < nmembs; i++) {
- req.entrynum = vinfo[i].nvi_vblocknr;
-
- error = nandfs_get_entry_block(mdt, dat,&req, &idx, 0);
- if (error)
- break;
-
- dat_entry = ((struct nandfs_dat_entry *) req.bp_entry->b_data);
- vinfo[i].nvi_start = dat_entry[idx].de_start;
- vinfo[i].nvi_end = dat_entry[idx].de_end;
- vinfo[i].nvi_blocknr = dat_entry[idx].de_blocknr;
-
- DPRINTF(DAT, ("%s: vinfo: %jx[%jx-%jx]->%jx\n",
- __func__, vinfo[i].nvi_vblocknr, vinfo[i].nvi_start,
- vinfo[i].nvi_end, vinfo[i].nvi_blocknr));
-
- brelse(req.bp_entry);
- }
-
- VOP_UNLOCK(NTOV(dat), 0);
- return (error);
-}
-
-int
-nandfs_get_dat_bdescs_ioctl(struct nandfs_device *nffsdev,
- struct nandfs_argv *nargv)
-{
- struct nandfs_bdesc *bd;
- size_t size;
- int error;
-
- size = nargv->nv_nmembs * sizeof(struct nandfs_bdesc);
- bd = malloc(size, M_NANDFSTEMP, M_WAITOK);
- error = copyin((void *)(uintptr_t)nargv->nv_base, bd, size);
- if (error) {
- free(bd, M_NANDFSTEMP);
- return (error);
- }
-
- error = nandfs_get_dat_bdescs(nffsdev, bd, nargv->nv_nmembs);
-
- if (error == 0)
- error = copyout(bd, (void *)(uintptr_t)nargv->nv_base, size);
-
- free(bd, M_NANDFSTEMP);
- return (error);
-}
-
-int
-nandfs_get_dat_bdescs(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd,
- uint32_t nmembs)
-{
- struct nandfs_node *dat_node;
- uint64_t map;
- uint32_t i;
- int error = 0;
-
- dat_node = nffsdev->nd_dat_node;
-
- VOP_LOCK(NTOV(dat_node), LK_EXCLUSIVE);
-
- for (i = 0; i < nmembs; i++) {
- DPRINTF(CLEAN,
- ("%s: bd ino:%#jx oblk:%#jx blocknr:%#jx off:%#jx\n",
- __func__, (uintmax_t)bd[i].bd_ino,
- (uintmax_t)bd[i].bd_oblocknr, (uintmax_t)bd[i].bd_blocknr,
- (uintmax_t)bd[i].bd_offset));
-
- error = nandfs_bmap_lookup(dat_node, bd[i].bd_offset, &map);
- if (error)
- break;
- bd[i].bd_blocknr = map;
- }
-
- VOP_UNLOCK(NTOV(dat_node), 0);
- return (error);
-}
diff --git a/sys/fs/nandfs/nandfs_dir.c b/sys/fs/nandfs/nandfs_dir.c
deleted file mode 100644
index 404edecfaa08..000000000000
--- a/sys/fs/nandfs/nandfs_dir.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/kernel.h>
-#include <sys/stat.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/signalvar.h>
-#include <sys/malloc.h>
-#include <sys/dirent.h>
-#include <sys/lockf.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include "nandfs_mount.h"
-#include "nandfs.h"
-#include "nandfs_subr.h"
-
-int
-nandfs_add_dirent(struct vnode *dvp, uint64_t ino, char *nameptr, long namelen,
- uint8_t type)
-{
- struct nandfs_node *dir_node = VTON(dvp);
- struct nandfs_dir_entry *dirent, *pdirent;
- uint32_t blocksize = dir_node->nn_nandfsdev->nd_blocksize;
- uint64_t filesize = dir_node->nn_inode.i_size;
- uint64_t inode_blks = dir_node->nn_inode.i_blocks;
- uint32_t off, rest;
- uint8_t *pos;
- struct buf *bp;
- int error;
-
- pdirent = NULL;
- bp = NULL;
- if (inode_blks) {
- error = nandfs_bread(dir_node, inode_blks - 1, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- pos = bp->b_data;
- off = 0;
- while (off < blocksize) {
- pdirent = (struct nandfs_dir_entry *) (pos + off);
- if (!pdirent->rec_len) {
- pdirent = NULL;
- break;
- }
- off += pdirent->rec_len;
- }
-
- if (pdirent)
- rest = pdirent->rec_len -
- NANDFS_DIR_REC_LEN(pdirent->name_len);
- else
- rest = blocksize;
-
- if (rest < NANDFS_DIR_REC_LEN(namelen)) {
- /* Do not update pdirent as new block is created */
- pdirent = NULL;
- brelse(bp);
- /* Set to NULL to create new */
- bp = NULL;
- filesize += rest;
- }
- }
-
- /* If no bp found create new */
- if (!bp) {
- error = nandfs_bcreate(dir_node, inode_blks, NOCRED, 0, &bp);
- if (error)
- return (error);
- off = 0;
- pos = bp->b_data;
- }
-
- /* Modify pdirent if exists */
- if (pdirent) {
- DPRINTF(LOOKUP, ("modify pdirent %p\n", pdirent));
- /* modify last de */
- off -= pdirent->rec_len;
- pdirent->rec_len =
- NANDFS_DIR_REC_LEN(pdirent->name_len);
- off += pdirent->rec_len;
- }
-
- /* Create new dirent */
- dirent = (struct nandfs_dir_entry *) (pos + off);
- dirent->rec_len = blocksize - off;
- dirent->inode = ino;
- dirent->name_len = namelen;
- memset(dirent->name, 0, NANDFS_DIR_NAME_LEN(namelen));
- memcpy(dirent->name, nameptr, namelen);
- dirent->file_type = type;
-
- filesize += NANDFS_DIR_REC_LEN(dirent->name_len);
-
- DPRINTF(LOOKUP, ("create dir_entry '%.*s' at %p with size %x "
- "new filesize: %jx\n",
- (int)namelen, dirent->name, dirent, dirent->rec_len,
- (uintmax_t)filesize));
-
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (error);
-
- dir_node->nn_inode.i_size = filesize;
- dir_node->nn_flags |= IN_CHANGE | IN_UPDATE;
- vnode_pager_setsize(dvp, filesize);
-
- return (0);
-}
-
-int
-nandfs_remove_dirent(struct vnode *dvp, struct nandfs_node *node,
- struct componentname *cnp)
-{
- struct nandfs_node *dir_node;
- struct nandfs_dir_entry *dirent, *pdirent;
- struct buf *bp;
- uint64_t filesize, blocknr, ino, offset;
- uint32_t blocksize, limit, off;
- uint16_t newsize;
- uint8_t *pos;
- int error, found;
-
- dir_node = VTON(dvp);
- filesize = dir_node->nn_inode.i_size;
- if (!filesize)
- return (0);
-
- if (node) {
- offset = node->nn_diroff;
- ino = node->nn_ino;
- } else {
- offset = dir_node->nn_diroff;
- ino = NANDFS_WHT_INO;
- }
-
- dirent = pdirent = NULL;
- blocksize = dir_node->nn_nandfsdev->nd_blocksize;
- blocknr = offset / blocksize;
-
- DPRINTF(LOOKUP, ("rm direntry dvp %p node %p ino %#jx at off %#jx\n",
- dvp, node, (uintmax_t)ino, (uintmax_t)offset));
-
- error = nandfs_bread(dir_node, blocknr, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- pos = bp->b_data;
- off = 0;
- found = 0;
- limit = offset % blocksize;
- pdirent = (struct nandfs_dir_entry *) bp->b_data;
- while (off <= limit) {
- dirent = (struct nandfs_dir_entry *) (pos + off);
-
- if ((off == limit) &&
- (dirent->inode == ino)) {
- found = 1;
- break;
- }
- if (dirent->inode != 0)
- pdirent = dirent;
- off += dirent->rec_len;
- }
-
- if (!found) {
- nandfs_error("cannot find entry to remove");
- brelse(bp);
- return (error);
- }
- DPRINTF(LOOKUP,
- ("rm dirent ino %#jx at %#x with size %#x\n",
- (uintmax_t)dirent->inode, off, dirent->rec_len));
-
- newsize = (uintptr_t)dirent - (uintptr_t)pdirent;
- newsize += dirent->rec_len;
- pdirent->rec_len = newsize;
- dirent->inode = 0;
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (error);
-
- dir_node->nn_flags |= IN_CHANGE | IN_UPDATE;
- /* If last one modify filesize */
- if ((offset + NANDFS_DIR_REC_LEN(dirent->name_len)) == filesize) {
- filesize = blocknr * blocksize +
- ((uintptr_t)pdirent - (uintptr_t)pos) +
- NANDFS_DIR_REC_LEN(pdirent->name_len);
- dir_node->nn_inode.i_size = filesize;
- }
-
- return (0);
-}
-
-int
-nandfs_update_parent_dir(struct vnode *dvp, uint64_t newparent)
-{
- struct nandfs_dir_entry *dirent;
- struct nandfs_node *dir_node;
- struct buf *bp;
- int error;
-
- dir_node = VTON(dvp);
- error = nandfs_bread(dir_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- dirent = (struct nandfs_dir_entry *)bp->b_data;
- dirent->inode = newparent;
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (error);
-
- return (0);
-}
-
-int
-nandfs_update_dirent(struct vnode *dvp, struct nandfs_node *fnode,
- struct nandfs_node *tnode)
-{
- struct nandfs_node *dir_node;
- struct nandfs_dir_entry *dirent;
- struct buf *bp;
- uint64_t file_size, blocknr;
- uint32_t blocksize, off;
- uint8_t *pos;
- int error;
-
- dir_node = VTON(dvp);
- file_size = dir_node->nn_inode.i_size;
- if (!file_size)
- return (0);
-
- DPRINTF(LOOKUP,
- ("chg direntry dvp %p ino %#jx to in %#jx at off %#jx\n",
- dvp, (uintmax_t)tnode->nn_ino, (uintmax_t)fnode->nn_ino,
- (uintmax_t)tnode->nn_diroff));
-
- blocksize = dir_node->nn_nandfsdev->nd_blocksize;
- blocknr = tnode->nn_diroff / blocksize;
- off = tnode->nn_diroff % blocksize;
- error = nandfs_bread(dir_node, blocknr, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- pos = bp->b_data;
- dirent = (struct nandfs_dir_entry *) (pos + off);
- KASSERT((dirent->inode == tnode->nn_ino),
- ("direntry mismatch"));
-
- dirent->inode = fnode->nn_ino;
- error = nandfs_dirty_buf(bp, 0);
- if (error)
- return (error);
-
- return (0);
-}
-
-int
-nandfs_init_dir(struct vnode *dvp, uint64_t ino, uint64_t parent_ino)
-{
-
- if (nandfs_add_dirent(dvp, parent_ino, "..", 2, DT_DIR) ||
- nandfs_add_dirent(dvp, ino, ".", 1, DT_DIR)) {
- nandfs_error("%s: cannot initialize dir ino:%jd(pino:%jd)\n",
- __func__, ino, parent_ino);
- return (-1);
- }
- return (0);
-}
diff --git a/sys/fs/nandfs/nandfs_fs.h b/sys/fs/nandfs/nandfs_fs.h
deleted file mode 100644
index 9cb440ebcb90..000000000000
--- a/sys/fs/nandfs/nandfs_fs.h
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Original definitions written by Koji Sato <koji@osrg.net>
- * and Ryusuke Konishi <ryusuke@osrg.net>
- * From: NetBSD: nandfs_fs.h,v 1.1 2009/07/18 16:31:42 reinoud
- *
- * $FreeBSD$
- */
-
-#ifndef _NANDFS_FS_H
-#define _NANDFS_FS_H
-
-#include <sys/uuid.h>
-
-#define MNINDIR(fsdev) ((fsdev)->nd_blocksize / sizeof(nandfs_daddr_t))
-
-/*
- * Inode structure. There are a few dedicated inode numbers that are
- * defined here first.
- */
-#define NANDFS_WHT_INO 1 /* Whiteout ino */
-#define NANDFS_ROOT_INO 2 /* Root file inode */
-#define NANDFS_DAT_INO 3 /* DAT file */
-#define NANDFS_CPFILE_INO 4 /* checkpoint file */
-#define NANDFS_SUFILE_INO 5 /* segment usage file */
-#define NANDFS_IFILE_INO 6 /* ifile */
-#define NANDFS_GC_INO 7 /* Cleanerd node */
-#define NANDFS_ATIME_INO 8 /* Atime file (reserved) */
-#define NANDFS_XATTR_INO 9 /* Xattribute file (reserved) */
-#define NANDFS_SKETCH_INO 10 /* Sketch file (obsolete) */
-#define NANDFS_USER_INO 11 /* First user's file inode number */
-
-#define NANDFS_SYS_NODE(ino) \
- (((ino) >= NANDFS_DAT_INO) && ((ino) <= NANDFS_GC_INO))
-
-#define NANDFS_NDADDR 12 /* Direct addresses in inode. */
-#define NANDFS_NIADDR 3 /* Indirect addresses in inode. */
-
-typedef int64_t nandfs_daddr_t;
-typedef int64_t nandfs_lbn_t;
-
-struct nandfs_inode {
- uint64_t i_blocks; /* 0: size in device blocks */
- uint64_t i_size; /* 8: size in bytes */
- uint64_t i_ctime; /* 16: creation time in seconds */
- uint64_t i_mtime; /* 24: modification time in seconds part*/
- uint32_t i_ctime_nsec; /* 32: creation time nanoseconds part */
- uint32_t i_mtime_nsec; /* 36: modification time in nanoseconds */
- uint32_t i_uid; /* 40: user id */
- uint32_t i_gid; /* 44: group id */
- uint16_t i_mode; /* 48: file mode */
- uint16_t i_links_count; /* 50: number of references to the inode*/
- uint32_t i_flags; /* 52: NANDFS_*_FL flags */
- nandfs_daddr_t i_special; /* 56: special */
- nandfs_daddr_t i_db[NANDFS_NDADDR]; /* 64: Direct disk blocks. */
- nandfs_daddr_t i_ib[NANDFS_NIADDR]; /* 160: Indirect disk blocks. */
- uint64_t i_xattr; /* 184: reserved for extended attributes*/
- uint32_t i_generation; /* 192: file generation for NFS */
- uint32_t i_pad[15]; /* 196: make it 64 bits aligned */
-};
-
-#ifdef _KERNEL
-CTASSERT(sizeof(struct nandfs_inode) == 256);
-#endif
-
-/*
- * Each checkpoint/snapshot has a super root.
- *
- * The super root holds the inodes of the three system files: `dat', `cp' and
- * 'su' files. All other FS state is defined by those.
- *
- * It is CRC checksum'ed and time stamped.
- */
-
-struct nandfs_super_root {
- uint32_t sr_sum; /* check-sum */
- uint16_t sr_bytes; /* byte count of this structure */
- uint16_t sr_flags; /* reserved for flags */
- uint64_t sr_nongc_ctime; /* timestamp, not for cleaner(?) */
- struct nandfs_inode sr_dat; /* DAT, virt->phys translation inode */
- struct nandfs_inode sr_cpfile; /* CP, checkpoints inode */
- struct nandfs_inode sr_sufile; /* SU, segment usage inode */
-};
-
-#define NANDFS_SR_MDT_OFFSET(inode_size, i) \
- ((uint32_t)&((struct nandfs_super_root *)0)->sr_dat + \
- (inode_size) * (i))
-
-#define NANDFS_SR_DAT_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 0)
-#define NANDFS_SR_CPFILE_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 1)
-#define NANDFS_SR_SUFILE_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 2)
-#define NANDFS_SR_BYTES (sizeof(struct nandfs_super_root))
-
-/*
- * The superblock describes the basic structure and mount history. It also
- * records some sizes of structures found on the disc for sanity checks.
- *
- * The superblock is stored at two places: NANDFS_SB_OFFSET_BYTES and
- * NANDFS_SB2_OFFSET_BYTES.
- */
-
-/* File system states stored on media in superblock's sbp->s_state */
-#define NANDFS_VALID_FS 0x0001 /* cleanly unmounted and all is ok */
-#define NANDFS_ERROR_FS 0x0002 /* there were errors detected, fsck */
-#define NANDFS_RESIZE_FS 0x0004 /* resize required, XXX unknown flag*/
-#define NANDFS_MOUNT_STATE_BITS "\20\1VALID_FS\2ERROR_FS\3RESIZE_FS"
-
-/*
- * Brief description of control structures:
- *
- * NANDFS_NFSAREAS first blocks contain fsdata and some amount of super blocks.
- * Simple round-robin policy is used in order to choose which block will
- * contain new super block.
- *
- * Simple case with 2 blocks:
- * 1: fsdata sblock1 [sblock3 [sblock5 ..]]
- * 2: fsdata sblock2 [sblock4 [sblock6 ..]]
- */
-struct nandfs_fsdata {
- uint16_t f_magic;
- uint16_t f_bytes;
-
- uint32_t f_sum; /* checksum of fsdata */
- uint32_t f_rev_level; /* major disk format revision */
-
- uint64_t f_ctime; /* creation time (execution time
- of newfs) */
- /* Block size represented as: blocksize = 1 << (f_log_block_size + 10) */
- uint32_t f_log_block_size;
-
- uint16_t f_inode_size; /* size of an inode */
- uint16_t f_dat_entry_size; /* size of a dat entry */
- uint16_t f_checkpoint_size; /* size of a checkpoint */
- uint16_t f_segment_usage_size; /* size of a segment usage */
-
- uint16_t f_sbbytes; /* byte count of CRC calculation
- for super blocks. s_reserved
- is excluded! */
-
- uint16_t f_errors; /* behaviour on detecting errors */
-
- uint32_t f_erasesize;
- uint64_t f_nsegments; /* number of segm. in filesystem */
- nandfs_daddr_t f_first_data_block; /* 1st seg disk block number */
- uint32_t f_blocks_per_segment; /* number of blocks per segment */
- uint32_t f_r_segments_percentage; /* reserved segments percentage */
-
- struct uuid f_uuid; /* 128-bit uuid for volume */
- char f_volume_name[16]; /* volume name */
- uint32_t f_pad[104];
-} __packed;
-
-#ifdef _KERNEL
-CTASSERT(sizeof(struct nandfs_fsdata) == 512);
-#endif
-
-struct nandfs_super_block {
- uint16_t s_magic; /* magic value for identification */
-
- uint32_t s_sum; /* check sum of super block */
-
- uint64_t s_last_cno; /* last checkpoint number */
- uint64_t s_last_pseg; /* addr part. segm. written last */
- uint64_t s_last_seq; /* seq.number of seg written last */
- uint64_t s_free_blocks_count; /* free blocks count */
-
- uint64_t s_mtime; /* mount time */
- uint64_t s_wtime; /* write time */
- uint16_t s_state; /* file system state */
-
- char s_last_mounted[64]; /* directory where last mounted */
-
- uint32_t s_c_interval; /* commit interval of segment */
- uint32_t s_c_block_max; /* threshold of data amount for
- the segment construction */
- uint32_t s_reserved[32]; /* padding to end of the block */
-} __packed;
-
-#ifdef _KERNEL
-CTASSERT(sizeof(struct nandfs_super_block) == 256);
-#endif
-
-#define NANDFS_FSDATA_MAGIC 0xf8da
-#define NANDFS_SUPER_MAGIC 0x8008
-
-#define NANDFS_NFSAREAS 4
-#define NANDFS_DATA_OFFSET_BYTES(esize) (NANDFS_NFSAREAS * (esize))
-
-#define NANDFS_SBLOCK_OFFSET_BYTES (sizeof(struct nandfs_fsdata))
-
-#define NANDFS_DEF_BLOCKSIZE 4096
-#define NANDFS_MIN_BLOCKSIZE 512
-
-#define NANDFS_DEF_ERASESIZE (2 << 16)
-
-#define NANDFS_MIN_SEGSIZE NANDFS_DEF_ERASESIZE
-
-#define NANDFS_CURRENT_REV 9 /* current major revision */
-
-#define NANDFS_FSDATA_CRC_BYTES offsetof(struct nandfs_fsdata, f_pad)
-/* Bytes count of super_block for CRC-calculation */
-#define NANDFS_SB_BYTES offsetof(struct nandfs_super_block, s_reserved)
-
-/* Maximal count of links to a file */
-#define NANDFS_LINK_MAX 32000
-
-/*
- * Structure of a directory entry.
- *
- * Note that they can't span blocks; the rec_len fills out.
- */
-
-#define NANDFS_NAME_LEN 255
-struct nandfs_dir_entry {
- uint64_t inode; /* inode number */
- uint16_t rec_len; /* directory entry length */
- uint8_t name_len; /* name length */
- uint8_t file_type;
- char name[NANDFS_NAME_LEN]; /* file name */
- char pad;
-};
-
-/*
- * NANDFS_DIR_PAD defines the directory entries boundaries
- *
- * NOTE: It must be a multiple of 8
- */
-#define NANDFS_DIR_PAD 8
-#define NANDFS_DIR_ROUND (NANDFS_DIR_PAD - 1)
-#define NANDFS_DIR_NAME_OFFSET (offsetof(struct nandfs_dir_entry, name))
-#define NANDFS_DIR_REC_LEN(name_len) \
- (((name_len) + NANDFS_DIR_NAME_OFFSET + NANDFS_DIR_ROUND) \
- & ~NANDFS_DIR_ROUND)
-#define NANDFS_DIR_NAME_LEN(name_len) \
- (NANDFS_DIR_REC_LEN(name_len) - NANDFS_DIR_NAME_OFFSET)
-
-/*
- * NiLFS/NANDFS devides the disc into fixed length segments. Each segment is
- * filled with one or more partial segments of variable lengths.
- *
- * Each partial segment has a segment summary header followed by updates of
- * files and optionally a super root.
- */
-
-/*
- * Virtual to physical block translation information. For data blocks it maps
- * logical block number bi_blkoff to virtual block nr bi_vblocknr. For non
- * datablocks it is the virtual block number assigned to an indirect block
- * and has no bi_blkoff. The physical block number is the next
- * available data block in the partial segment after all the binfo's.
- */
-struct nandfs_binfo_v {
- uint64_t bi_ino; /* file's inode */
- uint64_t bi_vblocknr; /* assigned virtual block number */
- uint64_t bi_blkoff; /* for file's logical block number */
-};
-
-/*
- * DAT allocation. For data blocks just the logical block number that maps on
- * the next available data block in the partial segment after the binfo's.
- */
-struct nandfs_binfo_dat {
- uint64_t bi_ino;
- uint64_t bi_blkoff; /* DAT file's logical block number */
- uint8_t bi_level; /* whether this is meta block */
- uint8_t bi_pad[7];
-};
-
-#ifdef _KERNEL
-CTASSERT(sizeof(struct nandfs_binfo_v) == sizeof(struct nandfs_binfo_dat));
-#endif
-
-/* Convenience union for both types of binfo's */
-union nandfs_binfo {
- struct nandfs_binfo_v bi_v;
- struct nandfs_binfo_dat bi_dat;
-};
-
-/* Indirect buffers path */
-struct nandfs_indir {
- nandfs_daddr_t in_lbn;
- int in_off;
-};
-
-/* The (partial) segment summary */
-struct nandfs_segment_summary {
- uint32_t ss_datasum; /* CRC of complete data block */
- uint32_t ss_sumsum; /* CRC of segment summary only */
- uint32_t ss_magic; /* magic to identify segment summary */
- uint16_t ss_bytes; /* size of segment summary structure */
- uint16_t ss_flags; /* NANDFS_SS_* flags */
- uint64_t ss_seq; /* sequence number of this segm. sum */
- uint64_t ss_create; /* creation timestamp in seconds */
- uint64_t ss_next; /* blocknumber of next segment */
- uint32_t ss_nblocks; /* number of blocks used by summary */
- uint32_t ss_nbinfos; /* number of binfo structures */
- uint32_t ss_sumbytes; /* total size of segment summary */
- uint32_t ss_pad;
- /* stream of binfo structures */
-};
-
-#define NANDFS_SEGSUM_MAGIC 0x8e680011 /* segment summary magic number */
-
-/* Segment summary flags */
-#define NANDFS_SS_LOGBGN 0x0001 /* begins a logical segment */
-#define NANDFS_SS_LOGEND 0x0002 /* ends a logical segment */
-#define NANDFS_SS_SR 0x0004 /* has super root */
-#define NANDFS_SS_SYNDT 0x0008 /* includes data only updates */
-#define NANDFS_SS_GC 0x0010 /* segment written for cleaner operation */
-#define NANDFS_SS_FLAG_BITS "\20\1LOGBGN\2LOGEND\3SR\4SYNDT\5GC"
-
-/* Segment summary constrains */
-#define NANDFS_SEG_MIN_BLOCKS 16 /* minimum number of blocks in a
- full segment */
-#define NANDFS_PSEG_MIN_BLOCKS 2 /* minimum number of blocks in a
- partial segment */
-#define NANDFS_MIN_NRSVSEGS 8 /* minimum number of reserved
- segments */
-
-/*
- * Structure of DAT/inode file.
- *
- * A DAT file is divided into groups. The maximum number of groups is the
- * number of block group descriptors that fit into one block; this descriptor
- * only gives the number of free entries in the associated group.
- *
- * Each group has a block sized bitmap indicating if an entry is taken or
- * empty. Each bit stands for a DAT entry.
- *
- * The inode file has exactly the same format only the entries are inode
- * entries.
- */
-
-struct nandfs_block_group_desc {
- uint32_t bg_nfrees; /* num. free entries in block group */
-};
-
-/* DAT entry in a super root's DAT file */
-struct nandfs_dat_entry {
- uint64_t de_blocknr; /* block number */
- uint64_t de_start; /* valid from checkpoint */
- uint64_t de_end; /* valid till checkpoint */
- uint64_t de_rsv; /* reserved for future use */
-};
-
-/*
- * Structure of CP file.
- *
- * A snapshot is just a checkpoint only it's protected against removal by the
- * cleaner. The snapshots are kept on a double linked list of checkpoints.
- */
-struct nandfs_snapshot_list {
- uint64_t ssl_next; /* checkpoint nr. forward */
- uint64_t ssl_prev; /* checkpoint nr. back */
-};
-
-/* Checkpoint entry structure */
-struct nandfs_checkpoint {
- uint32_t cp_flags; /* NANDFS_CHECKPOINT_* flags */
- uint32_t cp_checkpoints_count; /* ZERO, not used anymore? */
- struct nandfs_snapshot_list cp_snapshot_list; /* list of snapshots */
- uint64_t cp_cno; /* checkpoint number */
- uint64_t cp_create; /* creation timestamp */
- uint64_t cp_nblk_inc; /* number of blocks incremented */
- uint64_t cp_blocks_count; /* reserved (might be deleted) */
- struct nandfs_inode cp_ifile_inode; /* inode file inode */
-};
-
-/* Checkpoint flags */
-#define NANDFS_CHECKPOINT_SNAPSHOT 1
-#define NANDFS_CHECKPOINT_INVALID 2
-#define NANDFS_CHECKPOINT_SKETCH 4
-#define NANDFS_CHECKPOINT_MINOR 8
-#define NANDFS_CHECKPOINT_BITS "\20\1SNAPSHOT\2INVALID\3SKETCH\4MINOR"
-
-/* Header of the checkpoint file */
-struct nandfs_cpfile_header {
- uint64_t ch_ncheckpoints; /* number of checkpoints */
- uint64_t ch_nsnapshots; /* number of snapshots */
- struct nandfs_snapshot_list ch_snapshot_list; /* snapshot list */
-};
-
-#define NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET \
- ((sizeof(struct nandfs_cpfile_header) + \
- sizeof(struct nandfs_checkpoint) - 1) / \
- sizeof(struct nandfs_checkpoint))
-
-
-#define NANDFS_NOSEGMENT 0xffffffff
-
-/*
- * Structure of SU file.
- *
- * The segment usage file sums up how each of the segments are used. They are
- * indexed by their segment number.
- */
-
-/* Segment usage entry */
-struct nandfs_segment_usage {
- uint64_t su_lastmod; /* last modified timestamp */
- uint32_t su_nblocks; /* number of blocks in segment */
- uint32_t su_flags; /* NANDFS_SEGMENT_USAGE_* flags */
-};
-
-/* Segment usage flag */
-#define NANDFS_SEGMENT_USAGE_ACTIVE 1
-#define NANDFS_SEGMENT_USAGE_DIRTY 2
-#define NANDFS_SEGMENT_USAGE_ERROR 4
-#define NANDFS_SEGMENT_USAGE_GC 8
-#define NANDFS_SEGMENT_USAGE_BITS "\20\1ACTIVE\2DIRTY\3ERROR"
-
-/* Header of the segment usage file */
-struct nandfs_sufile_header {
- uint64_t sh_ncleansegs; /* number of segments marked clean */
- uint64_t sh_ndirtysegs; /* number of segments marked dirty */
- uint64_t sh_last_alloc; /* last allocated segment number */
-};
-
-#define NANDFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET \
- ((sizeof(struct nandfs_sufile_header) + \
- sizeof(struct nandfs_segment_usage) - 1) / \
- sizeof(struct nandfs_segment_usage))
-
-struct nandfs_seg_stat {
- uint64_t nss_nsegs;
- uint64_t nss_ncleansegs;
- uint64_t nss_ndirtysegs;
- uint64_t nss_ctime;
- uint64_t nss_nongc_ctime;
- uint64_t nss_prot_seq;
-};
-
-enum {
- NANDFS_CHECKPOINT,
- NANDFS_SNAPSHOT
-};
-
-#define NANDFS_CPINFO_MAX 512
-
-struct nandfs_cpinfo {
- uint32_t nci_flags;
- uint32_t nci_pad;
- uint64_t nci_cno;
- uint64_t nci_create;
- uint64_t nci_nblk_inc;
- uint64_t nci_blocks_count;
- uint64_t nci_next;
-};
-
-#define NANDFS_SEGMENTS_MAX 512
-
-struct nandfs_suinfo {
- uint64_t nsi_num;
- uint64_t nsi_lastmod;
- uint32_t nsi_blocks;
- uint32_t nsi_flags;
-};
-
-#define NANDFS_VINFO_MAX 512
-
-struct nandfs_vinfo {
- uint64_t nvi_ino;
- uint64_t nvi_vblocknr;
- uint64_t nvi_start;
- uint64_t nvi_end;
- uint64_t nvi_blocknr;
- int nvi_alive;
-};
-
-struct nandfs_cpmode {
- uint64_t ncpm_cno;
- uint32_t ncpm_mode;
- uint32_t ncpm_pad;
-};
-
-struct nandfs_argv {
- uint64_t nv_base;
- uint32_t nv_nmembs;
- uint16_t nv_size;
- uint16_t nv_flags;
- uint64_t nv_index;
-};
-
-struct nandfs_cpstat {
- uint64_t ncp_cno;
- uint64_t ncp_ncps;
- uint64_t ncp_nss;
-};
-
-struct nandfs_period {
- uint64_t p_start;
- uint64_t p_end;
-};
-
-struct nandfs_vdesc {
- uint64_t vd_ino;
- uint64_t vd_cno;
- uint64_t vd_vblocknr;
- struct nandfs_period vd_period;
- uint64_t vd_blocknr;
- uint64_t vd_offset;
- uint32_t vd_flags;
- uint32_t vd_pad;
-};
-
-struct nandfs_bdesc {
- uint64_t bd_ino;
- uint64_t bd_oblocknr;
- uint64_t bd_blocknr;
- uint64_t bd_offset;
- uint32_t bd_level;
- uint32_t bd_alive;
-};
-
-#ifndef _KERNEL
-#ifndef MNAMELEN
-#define MNAMELEN 1024
-#endif
-#endif
-
-struct nandfs_fsinfo {
- struct nandfs_fsdata fs_fsdata;
- struct nandfs_super_block fs_super;
- char fs_dev[MNAMELEN];
-};
-
-#define NANDFS_MAX_MOUNTS 65535
-
-#define NANDFS_IOCTL_GET_SUSTAT _IOR('N', 100, struct nandfs_seg_stat)
-#define NANDFS_IOCTL_CHANGE_CPMODE _IOWR('N', 101, struct nandfs_cpmode)
-#define NANDFS_IOCTL_GET_CPINFO _IOWR('N', 102, struct nandfs_argv)
-#define NANDFS_IOCTL_DELETE_CP _IOWR('N', 103, uint64_t[2])
-#define NANDFS_IOCTL_GET_CPSTAT _IOR('N', 104, struct nandfs_cpstat)
-#define NANDFS_IOCTL_GET_SUINFO _IOWR('N', 105, struct nandfs_argv)
-#define NANDFS_IOCTL_GET_VINFO _IOWR('N', 106, struct nandfs_argv)
-#define NANDFS_IOCTL_GET_BDESCS _IOWR('N', 107, struct nandfs_argv)
-#define NANDFS_IOCTL_GET_FSINFO _IOR('N', 108, struct nandfs_fsinfo)
-#define NANDFS_IOCTL_MAKE_SNAP _IOWR('N', 109, uint64_t)
-#define NANDFS_IOCTL_DELETE_SNAP _IOWR('N', 110, uint64_t)
-#define NANDFS_IOCTL_SYNC _IOWR('N', 111, uint64_t)
-
-#endif /* _NANDFS_FS_H */
diff --git a/sys/fs/nandfs/nandfs_ifile.c b/sys/fs/nandfs/nandfs_ifile.c
deleted file mode 100644
index 2c10bbac1ffe..000000000000
--- a/sys/fs/nandfs/nandfs_ifile.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/sysctl.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-int
-nandfs_node_create(struct nandfsmount *nmp, struct nandfs_node **node,
- uint16_t mode)
-{
- struct nandfs_alloc_request req;
- struct nandfs_device *nandfsdev;
- struct nandfs_mdt *mdt;
- struct nandfs_node *ifile;
- struct nandfs_inode *inode;
- struct vnode *vp;
- uint32_t entry;
- int error = 0;
-
- nandfsdev = nmp->nm_nandfsdev;
- mdt = &nandfsdev->nd_ifile_mdt;
- ifile = nmp->nm_ifile_node;
- vp = NTOV(ifile);
-
- VOP_LOCK(vp, LK_EXCLUSIVE);
- /* Allocate new inode in ifile */
- req.entrynum = nandfsdev->nd_last_ino + 1;
- error = nandfs_find_free_entry(mdt, ifile, &req);
- if (error) {
- VOP_UNLOCK(vp, 0);
- return (error);
- }
-
- error = nandfs_get_entry_block(mdt, ifile, &req, &entry, 1);
- if (error) {
- VOP_UNLOCK(vp, 0);
- return (error);
- }
-
- /* Inode initialization */
- inode = ((struct nandfs_inode *) req.bp_entry->b_data) + entry;
- nandfs_inode_init(inode, mode);
-
- error = nandfs_alloc_entry(mdt, &req);
- if (error) {
- VOP_UNLOCK(vp, 0);
- return (error);
- }
-
- VOP_UNLOCK(vp, 0);
-
- nandfsdev->nd_last_ino = req.entrynum;
- error = nandfs_get_node(nmp, req.entrynum, node);
- DPRINTF(IFILE, ("%s: node: %p ino: %#jx\n",
- __func__, node, (uintmax_t)((*node)->nn_ino)));
-
- return (error);
-}
-
-int
-nandfs_node_destroy(struct nandfs_node *node)
-{
- struct nandfs_alloc_request req;
- struct nandfsmount *nmp;
- struct nandfs_mdt *mdt;
- struct nandfs_node *ifile;
- struct vnode *vp;
- int error = 0;
-
- nmp = node->nn_nmp;
- req.entrynum = node->nn_ino;
- mdt = &nmp->nm_nandfsdev->nd_ifile_mdt;
- ifile = nmp->nm_ifile_node;
- vp = NTOV(ifile);
-
- DPRINTF(IFILE, ("%s: destroy node: %p ino: %#jx\n",
- __func__, node, (uintmax_t)node->nn_ino));
- VOP_LOCK(vp, LK_EXCLUSIVE);
-
- error = nandfs_find_entry(mdt, ifile, &req);
- if (error) {
- nandfs_error("%s: finding entry error:%d node %p(%jx)",
- __func__, error, node, node->nn_ino);
- VOP_UNLOCK(vp, 0);
- return (error);
- }
-
- nandfs_inode_destroy(&node->nn_inode);
-
- error = nandfs_free_entry(mdt, &req);
- if (error) {
- nandfs_error("%s: freing entry error:%d node %p(%jx)",
- __func__, error, node, node->nn_ino);
- VOP_UNLOCK(vp, 0);
- return (error);
- }
-
- VOP_UNLOCK(vp, 0);
- DPRINTF(IFILE, ("%s: freed node %p ino %#jx\n",
- __func__, node, (uintmax_t)node->nn_ino));
- return (error);
-}
-
-int
-nandfs_node_update(struct nandfs_node *node)
-{
- struct nandfs_alloc_request req;
- struct nandfsmount *nmp;
- struct nandfs_mdt *mdt;
- struct nandfs_node *ifile;
- struct nandfs_inode *inode;
- uint32_t index;
- int error = 0;
-
- nmp = node->nn_nmp;
- ifile = nmp->nm_ifile_node;
- ASSERT_VOP_LOCKED(NTOV(ifile), __func__);
-
- req.entrynum = node->nn_ino;
- mdt = &nmp->nm_nandfsdev->nd_ifile_mdt;
-
- DPRINTF(IFILE, ("%s: node:%p ino:%#jx\n",
- __func__, &node->nn_inode, (uintmax_t)node->nn_ino));
-
- error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0);
- if (error) {
- printf("nandfs_get_entry_block returned with ERROR=%d\n",
- error);
- return (error);
- }
-
- inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index;
- memcpy(inode, &node->nn_inode, sizeof(*inode));
- error = nandfs_dirty_buf(req.bp_entry, 0);
-
- return (error);
-}
-
-int
-nandfs_get_node_entry(struct nandfsmount *nmp, struct nandfs_inode **inode,
- uint64_t ino, struct buf **bp)
-{
- struct nandfs_alloc_request req;
- struct nandfs_mdt *mdt;
- struct nandfs_node *ifile;
- struct vnode *vp;
- uint32_t index;
- int error = 0;
-
- req.entrynum = ino;
- mdt = &nmp->nm_nandfsdev->nd_ifile_mdt;
- ifile = nmp->nm_ifile_node;
- vp = NTOV(ifile);
-
- VOP_LOCK(vp, LK_EXCLUSIVE);
- error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0);
- if (error) {
- VOP_UNLOCK(vp, 0);
- return (error);
- }
-
- *inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index;
- *bp = req.bp_entry;
- VOP_UNLOCK(vp, 0);
- return (0);
-}
-
diff --git a/sys/fs/nandfs/nandfs_mount.h b/sys/fs/nandfs/nandfs_mount.h
deleted file mode 100644
index cc6e30eb0bbd..000000000000
--- a/sys/fs/nandfs/nandfs_mount.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the
- * NetBSD Project. See http://www.NetBSD.org/ for
- * information about NetBSD.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs_mount.h,v 1.1 2009/07/18 16:31:42 reinoud
- *
- * $FreeBSD$
- */
-
-#ifndef _FS_NANDFS_NANDFS_MOUNT_H_
-#define _FS_NANDFS_NANDFS_MOUNT_H_
-
-/*
- * Arguments to mount NANDFS filingsystem.
- */
-
-struct nandfs_args {
- char *fspec; /* mount specifier */
- int64_t cpno; /* checkpoint number */
-};
-
-#endif /* !_FS_NANDFS_NANDFS_MOUNT_H_ */
-
diff --git a/sys/fs/nandfs/nandfs_segment.c b/sys/fs/nandfs/nandfs_segment.c
deleted file mode 100644
index 36efc89af409..000000000000
--- a/sys/fs/nandfs/nandfs_segment.c
+++ /dev/null
@@ -1,1314 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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 "opt_ddb.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/gsb_crc32.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/rwlock.h>
-#include <sys/sysctl.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-#include <sys/libkern.h>
-
-#include <ddb/ddb.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-static int
-nandfs_new_segment(struct nandfs_device *fsdev)
-{
- int error = 0;
- uint64_t new;
-
- error = nandfs_alloc_segment(fsdev, &new);
- if (!error) {
- fsdev->nd_seg_num = fsdev->nd_next_seg_num;
- fsdev->nd_next_seg_num = new;
- }
- DPRINTF(SYNC, ("%s: new segment %jx next %jx error %d\n",
- __func__, (uintmax_t)fsdev->nd_seg_num, (uintmax_t)new, error));
- if (error)
- nandfs_error("%s: cannot create segment error %d\n",
- __func__, error);
-
- return (error);
-}
-
-static int
-create_segment(struct nandfs_seginfo *seginfo)
-{
- struct nandfs_segment *seg;
- struct nandfs_device *fsdev;
- struct nandfs_segment *prev;
- struct buf *bp;
- uint64_t start_block, curr;
- uint32_t blks_per_seg, nblocks;
- int error;
-
- fsdev = seginfo->fsdev;
- prev = seginfo->curseg;
- blks_per_seg = fsdev->nd_fsdata.f_blocks_per_segment;
- nblocks = fsdev->nd_last_segsum.ss_nblocks;
-
- if (!prev) {
- vfs_timestamp(&fsdev->nd_ts);
- /* Touch current segment */
- error = nandfs_touch_segment(fsdev, fsdev->nd_seg_num);
- if (error) {
- nandfs_error("%s: cannot preallocate segment %jx\n",
- __func__, fsdev->nd_seg_num);
- return (error);
- }
- error = nandfs_touch_segment(fsdev, 0);
- if (error) {
- nandfs_error("%s: cannot dirty block with segment 0\n",
- __func__);
- return (error);
- }
- start_block = fsdev->nd_last_pseg + (uint64_t)nblocks;
- /*
- * XXX Hack
- */
- if (blks_per_seg - (start_block % blks_per_seg) - 1 == 0)
- start_block++;
- curr = nandfs_get_segnum_of_block(fsdev, start_block);
- /* Allocate new segment if last one is full */
- if (fsdev->nd_seg_num != curr) {
- error = nandfs_new_segment(fsdev);
- if (error) {
- nandfs_error("%s: cannot create new segment\n",
- __func__);
- return (error);
- }
- /*
- * XXX Hack
- */
- nandfs_get_segment_range(fsdev, fsdev->nd_seg_num, &start_block, NULL);
- }
- } else {
- nandfs_get_segment_range(fsdev, fsdev->nd_next_seg_num,
- &start_block, NULL);
-
- /* Touch current segment and allocate and touch new one */
- error = nandfs_new_segment(fsdev);
- if (error) {
- nandfs_error("%s: cannot create next segment\n",
- __func__);
- return (error);
- }
-
- /* Reiterate in case new buf is dirty */
- seginfo->reiterate = 1;
- }
-
- /* Allocate and initialize nandfs_segment structure */
- seg = malloc(sizeof(*seg), M_DEVBUF, M_WAITOK|M_ZERO);
- TAILQ_INIT(&seg->segsum);
- TAILQ_INIT(&seg->data);
- seg->fsdev = fsdev;
- seg->start_block = start_block;
- seg->num_blocks = blks_per_seg - (start_block % blks_per_seg) - 1;
- seg->seg_num = fsdev->nd_seg_num;
- seg->seg_next = fsdev->nd_next_seg_num;
- seg->segsum_blocks = 1;
- seg->bytes_left = fsdev->nd_blocksize -
- sizeof(struct nandfs_segment_summary);
- seg->segsum_bytes = sizeof(struct nandfs_segment_summary);
-
- /* Allocate buffer for segment summary */
- bp = getblk(fsdev->nd_devvp, nandfs_block_to_dblock(fsdev,
- seg->start_block), fsdev->nd_blocksize, 0, 0, 0);
- bzero(bp->b_data, seginfo->fsdev->nd_blocksize);
- bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj;
- bp->b_flags |= B_MANAGED;
-
- /* Add buffer to segment */
- TAILQ_INSERT_TAIL(&seg->segsum, bp, b_cluster.cluster_entry);
- seg->current_off = bp->b_data + sizeof(struct nandfs_segment_summary);
-
- DPRINTF(SYNC, ("%s: seg %p : initial settings: start %#jx size :%#x\n",
- __func__, seg, (uintmax_t)seg->start_block, seg->num_blocks));
- DPRINTF(SYNC, ("%s: seg->seg_num %#jx cno %#jx next %#jx\n", __func__,
- (uintmax_t)seg->seg_num, (uintmax_t)(fsdev->nd_last_cno + 1),
- (uintmax_t)seg->seg_next));
-
- if (!prev)
- LIST_INSERT_HEAD(&seginfo->seg_list, seg, seg_link);
- else
- LIST_INSERT_AFTER(prev, seg, seg_link);
-
- seginfo->curseg = seg;
-
- return (0);
-}
-
-static int
-delete_segment(struct nandfs_seginfo *seginfo)
-{
- struct nandfs_segment *seg, *tseg;
- struct buf *bp, *tbp;
-
- LIST_FOREACH_SAFE(seg, &seginfo->seg_list, seg_link, tseg) {
- TAILQ_FOREACH_SAFE(bp, &seg->segsum, b_cluster.cluster_entry,
- tbp) {
- TAILQ_REMOVE(&seg->segsum, bp, b_cluster.cluster_entry);
- bp->b_flags &= ~B_MANAGED;
- brelse(bp);
- }
-
- LIST_REMOVE(seg, seg_link);
- free(seg, M_DEVBUF);
- }
-
- return (0);
-}
-
-static int
-create_seginfo(struct nandfs_device *fsdev, struct nandfs_seginfo **seginfo)
-{
- struct nandfs_seginfo *info;
-
- info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK);
-
- LIST_INIT(&info->seg_list);
- info->fsdev = fsdev;
- info->curseg = NULL;
- info->blocks = 0;
- *seginfo = info;
- fsdev->nd_seginfo = info;
- return (0);
-}
-
-static int
-delete_seginfo(struct nandfs_seginfo *seginfo)
-{
- struct nandfs_device *nffsdev;
-
- nffsdev = seginfo->fsdev;
- delete_segment(seginfo);
- nffsdev->nd_seginfo = NULL;
- free(seginfo, M_DEVBUF);
-
- return (0);
-}
-
-static int
-nandfs_create_superroot_block(struct nandfs_seginfo *seginfo,
- struct buf **newbp)
-{
- struct buf *bp;
- int error;
-
- bp = nandfs_geteblk(seginfo->fsdev->nd_blocksize, GB_NOWAIT_BD);
-
- bzero(bp->b_data, seginfo->fsdev->nd_blocksize);
- bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj;
- bp->b_flags |= B_MANAGED;
-
- if (!(seginfo->curseg) || !seginfo->curseg->num_blocks) {
- error = create_segment(seginfo);
- if (error) {
- brelse(bp);
- nandfs_error("%s: no segment for superroot\n",
- __func__);
- return (error);
- }
- }
-
- TAILQ_INSERT_TAIL(&seginfo->curseg->data, bp, b_cluster.cluster_entry);
-
- seginfo->curseg->nblocks++;
- seginfo->curseg->num_blocks--;
- seginfo->blocks++;
-
- *newbp = bp;
- return (0);
-}
-
-static int
-nandfs_add_superroot(struct nandfs_seginfo *seginfo)
-{
- struct nandfs_device *fsdev;
- struct nandfs_super_root *sr;
- struct buf *bp = NULL;
- uint64_t crc_skip;
- uint32_t crc_calc;
- int error;
-
- fsdev = seginfo->fsdev;
-
- error = nandfs_create_superroot_block(seginfo, &bp);
- if (error) {
- nandfs_error("%s: cannot add superroot\n", __func__);
- return (error);
- }
-
- sr = (struct nandfs_super_root *)bp->b_data;
- /* Save superroot CRC */
- sr->sr_bytes = NANDFS_SR_BYTES;
- sr->sr_flags = 0;
- sr->sr_nongc_ctime = 0;
-
- memcpy(&sr->sr_dat, &fsdev->nd_dat_node->nn_inode,
- sizeof(struct nandfs_inode));
- memcpy(&sr->sr_cpfile, &fsdev->nd_cp_node->nn_inode,
- sizeof(struct nandfs_inode));
- memcpy(&sr->sr_sufile, &fsdev->nd_su_node->nn_inode,
- sizeof(struct nandfs_inode));
-
- crc_skip = sizeof(sr->sr_sum);
- crc_calc = crc32((uint8_t *)sr + crc_skip, NANDFS_SR_BYTES - crc_skip);
-
- sr->sr_sum = crc_calc;
-
- bp->b_flags |= B_MANAGED;
- bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj;
-
- bp->b_flags &= ~B_INVAL;
- nandfs_dirty_bufs_increment(fsdev);
- DPRINTF(SYNC, ("%s: bp:%p\n", __func__, bp));
-
- return (0);
-}
-
-static int
-nandfs_add_segsum_block(struct nandfs_seginfo *seginfo, struct buf **newbp)
-{
- struct nandfs_device *fsdev;
- nandfs_daddr_t blk;
- struct buf *bp;
- int error;
-
- if (!(seginfo->curseg) || seginfo->curseg->num_blocks <= 1) {
- error = create_segment(seginfo);
- if (error) {
- nandfs_error("%s: error:%d when creating segment\n",
- __func__, error);
- return (error);
- }
- *newbp = TAILQ_FIRST(&seginfo->curseg->segsum);
- return (0);
- }
-
- fsdev = seginfo->fsdev;
- blk = nandfs_block_to_dblock(fsdev, seginfo->curseg->start_block +
- seginfo->curseg->segsum_blocks);
-
- bp = getblk(fsdev->nd_devvp, blk, fsdev->nd_blocksize, 0, 0, 0);
-
- bzero(bp->b_data, seginfo->fsdev->nd_blocksize);
- bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj;
- bp->b_flags |= B_MANAGED;
-
- TAILQ_INSERT_TAIL(&seginfo->curseg->segsum, bp,
- b_cluster.cluster_entry);
- seginfo->curseg->num_blocks--;
-
- seginfo->curseg->segsum_blocks++;
- seginfo->curseg->bytes_left = seginfo->fsdev->nd_blocksize;
- seginfo->curseg->current_off = bp->b_data;
- seginfo->blocks++;
-
- *newbp = bp;
-
- DPRINTF(SYNC, ("%s: bp %p\n", __func__, bp));
-
- return (0);
-}
-
-static int
-nandfs_add_blocks(struct nandfs_seginfo *seginfo, struct nandfs_node *node,
- struct buf *bp)
-{
- union nandfs_binfo *binfo;
- struct buf *seg_bp;
- int error;
-
- if (!(seginfo->curseg) || !seginfo->curseg->num_blocks) {
- error = create_segment(seginfo);
- if (error) {
- nandfs_error("%s: error:%d when creating segment\n",
- __func__, error);
- return (error);
- }
- }
-
- if (seginfo->curseg->bytes_left < sizeof(union nandfs_binfo)) {
- error = nandfs_add_segsum_block(seginfo, &seg_bp);
- if (error) {
- nandfs_error("%s: error:%d when adding segsum\n",
- __func__, error);
- return (error);
- }
- }
- binfo = (union nandfs_binfo *)seginfo->curseg->current_off;
-
- if (node->nn_ino != NANDFS_DAT_INO) {
- binfo->bi_v.bi_blkoff = bp->b_lblkno;
- binfo->bi_v.bi_ino = node->nn_ino;
- } else {
- binfo->bi_dat.bi_blkoff = bp->b_lblkno;
- binfo->bi_dat.bi_ino = node->nn_ino;
- if (NANDFS_IS_INDIRECT(bp))
- binfo->bi_dat.bi_level = 1;
- else
- binfo->bi_dat.bi_level = 0;
- }
- binfo++;
-
- seginfo->curseg->bytes_left -= sizeof(union nandfs_binfo);
- seginfo->curseg->segsum_bytes += sizeof(union nandfs_binfo);
- seginfo->curseg->current_off = (char *)binfo;
-
- TAILQ_INSERT_TAIL(&seginfo->curseg->data, bp, b_cluster.cluster_entry);
-
- seginfo->curseg->nbinfos++;
- seginfo->curseg->nblocks++;
- seginfo->curseg->num_blocks--;
- seginfo->blocks++;
-
- DPRINTF(SYNC, ("%s: bp (%p) number %x (left %x)\n",
- __func__, bp, seginfo->curseg->nblocks,
- seginfo->curseg->num_blocks));
- return (0);
-}
-
-static int
-nandfs_iterate_dirty_buf(struct vnode *vp, struct nandfs_seginfo *seginfo,
- uint8_t hold)
-{
- struct buf *bp, *tbd;
- struct bufobj *bo;
- struct nandfs_node *node;
- int error;
-
- node = VTON(vp);
- bo = &vp->v_bufobj;
-
- ASSERT_VOP_ELOCKED(vp, __func__);
-
- /* Iterate dirty data bufs */
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, tbd) {
- DPRINTF(SYNC, ("%s: vp (%p): bp (%p) with lblkno %jx ino %jx "
- "add buf\n", __func__, vp, bp, bp->b_lblkno, node->nn_ino));
-
- if (!(NANDFS_ISGATHERED(bp))) {
- error = nandfs_bmap_update_dat(node,
- nandfs_vblk_get(bp), bp);
- if (error)
- return (error);
- NANDFS_GATHER(bp);
- nandfs_add_blocks(seginfo, node, bp);
- }
- }
-
- return (0);
-}
-
-static int
-nandfs_iterate_system_vnode(struct nandfs_node *node,
- struct nandfs_seginfo *seginfo)
-{
- struct vnode *vp;
- int nblocks;
- uint8_t hold = 0;
-
- if (node->nn_ino != NANDFS_IFILE_INO)
- hold = 1;
-
- vp = NTOV(node);
-
- nblocks = vp->v_bufobj.bo_dirty.bv_cnt;
- DPRINTF(SYNC, ("%s: vp (%p): nblocks %x ino %jx\n",
- __func__, vp, nblocks, node->nn_ino));
-
- if (nblocks)
- nandfs_iterate_dirty_buf(vp, seginfo, hold);
-
- return (0);
-}
-
-static int
-nandfs_iterate_dirty_vnodes(struct mount *mp, struct nandfs_seginfo *seginfo)
-{
- struct nandfs_node *nandfs_node;
- struct vnode *vp, *mvp;
- struct thread *td;
- struct bufobj *bo;
- int error, update;
-
- td = curthread;
-
- MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) {
- update = 0;
-
- if (mp->mnt_syncer == vp || VOP_ISLOCKED(vp)) {
- VI_UNLOCK(vp);
- continue;
- }
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT, td) != 0)
- continue;
-
- nandfs_node = VTON(vp);
- if (nandfs_node->nn_flags & IN_MODIFIED) {
- nandfs_node->nn_flags &= ~(IN_MODIFIED);
- update = 1;
- }
-
- bo = &vp->v_bufobj;
- BO_LOCK(bo);
- if (vp->v_bufobj.bo_dirty.bv_cnt) {
- error = nandfs_iterate_dirty_buf(vp, seginfo, 0);
- if (error) {
- nandfs_error("%s: cannot iterate vnode:%p "
- "err:%d\n", __func__, vp, error);
- vput(vp);
- BO_UNLOCK(bo);
- return (error);
- }
- update = 1;
- } else
- vput(vp);
- BO_UNLOCK(bo);
-
- if (update)
- nandfs_node_update(nandfs_node);
- }
-
- return (0);
-}
-
-static int
-nandfs_update_phys_block(struct nandfs_device *fsdev, struct buf *bp,
- uint64_t phys_blknr, union nandfs_binfo *binfo)
-{
- struct nandfs_node *node, *dat;
- struct vnode *vp;
- uint64_t new_blknr;
- int error;
-
- vp = bp->b_vp;
- node = VTON(vp);
- new_blknr = nandfs_vblk_get(bp);
- dat = fsdev->nd_dat_node;
-
- DPRINTF(BMAP, ("%s: ino %#jx lblk %#jx: vblk %#jx -> %#jx\n",
- __func__, (uintmax_t)node->nn_ino, (uintmax_t)bp->b_lblkno,
- (uintmax_t)new_blknr, (uintmax_t)phys_blknr));
-
- if (node->nn_ino != NANDFS_DAT_INO) {
- KASSERT((new_blknr != 0), ("vblk for bp %p is 0", bp));
-
- nandfs_vblock_assign(fsdev, new_blknr, phys_blknr);
- binfo->bi_v.bi_vblocknr = new_blknr;
- binfo->bi_v.bi_blkoff = bp->b_lblkno;
- binfo->bi_v.bi_ino = node->nn_ino;
- } else {
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- error = nandfs_bmap_update_block(node, bp, phys_blknr);
- if (error) {
- nandfs_error("%s: error updating block:%jx for bp:%p\n",
- __func__, (uintmax_t)phys_blknr, bp);
- VOP_UNLOCK(NTOV(dat), 0);
- return (error);
- }
- VOP_UNLOCK(NTOV(dat), 0);
- binfo->bi_dat.bi_blkoff = bp->b_lblkno;
- binfo->bi_dat.bi_ino = node->nn_ino;
- if (NANDFS_IS_INDIRECT(bp))
- binfo->bi_dat.bi_level = 1;
- else
- binfo->bi_dat.bi_level = 0;
- }
-
- return (0);
-}
-
-#define NBINFO(off) ((off) + sizeof(union nandfs_binfo))
-static int
-nandfs_segment_assign_pblk(struct nandfs_segment *nfsseg)
-{
- struct nandfs_device *fsdev;
- union nandfs_binfo *binfo;
- struct buf *bp, *seg_bp;
- uint64_t blocknr;
- uint32_t curr_off, blocksize;
- int error;
-
- fsdev = nfsseg->fsdev;
- blocksize = fsdev->nd_blocksize;
-
- blocknr = nfsseg->start_block + nfsseg->segsum_blocks;
- seg_bp = TAILQ_FIRST(&nfsseg->segsum);
- DPRINTF(SYNC, ("%s: seg:%p segsum bp:%p data:%p\n",
- __func__, nfsseg, seg_bp, seg_bp->b_data));
-
- binfo = (union nandfs_binfo *)(seg_bp->b_data +
- sizeof(struct nandfs_segment_summary));
- curr_off = sizeof(struct nandfs_segment_summary);
-
- TAILQ_FOREACH(bp, &nfsseg->data, b_cluster.cluster_entry) {
- KASSERT((bp->b_vp), ("bp %p has not vp", bp));
-
- DPRINTF(BMAP, ("\n\n%s: assign buf %p for ino %#jx next %p\n",
- __func__, bp, (uintmax_t)VTON(bp->b_vp)->nn_ino,
- TAILQ_NEXT(bp, b_cluster.cluster_entry)));
-
- if (NBINFO(curr_off) > blocksize) {
- seg_bp = TAILQ_NEXT(seg_bp, b_cluster.cluster_entry);
- binfo = (union nandfs_binfo *)seg_bp->b_data;
- curr_off = 0;
- DPRINTF(SYNC, ("%s: next segsum %p data %p\n",
- __func__, seg_bp, seg_bp->b_data));
- }
-
- error = nandfs_update_phys_block(fsdev, bp, blocknr, binfo);
- if (error) {
- nandfs_error("%s: err:%d when updatinng phys block:%jx"
- " for bp:%p and binfo:%p\n", __func__, error,
- (uintmax_t)blocknr, bp, binfo);
- return (error);
- }
- binfo++;
- curr_off = NBINFO(curr_off);
-
- blocknr++;
- }
-
- return (0);
-}
-
-static int
-nandfs_seginfo_assign_pblk(struct nandfs_seginfo *seginfo)
-{
- struct nandfs_segment *nfsseg;
- int error = 0;
-
- LIST_FOREACH(nfsseg, &seginfo->seg_list, seg_link) {
- error = nandfs_segment_assign_pblk(nfsseg);
- if (error)
- break;
- }
-
- return (error);
-}
-
-static struct nandfs_segment_summary *
-nandfs_fill_segsum(struct nandfs_segment *seg, int has_sr)
-{
- struct nandfs_segment_summary *ss;
- struct nandfs_device *fsdev;
- struct buf *bp;
- uint32_t rest, segsum_size, blocksize, crc_calc;
- uint16_t flags;
- uint8_t *crc_area, crc_skip;
-
- DPRINTF(SYNC, ("%s: seg %#jx nblocks %#x sumbytes %#x\n",
- __func__, (uintmax_t) seg->seg_num,
- seg->nblocks + seg->segsum_blocks,
- seg->segsum_bytes));
-
- fsdev = seg->fsdev;
-
- flags = NANDFS_SS_LOGBGN | NANDFS_SS_LOGEND;
- if (has_sr)
- flags |= NANDFS_SS_SR;
-
- bp = TAILQ_FIRST(&seg->segsum);
- ss = (struct nandfs_segment_summary *) bp->b_data;
- ss->ss_magic = NANDFS_SEGSUM_MAGIC;
- ss->ss_bytes = sizeof(struct nandfs_segment_summary);
- ss->ss_flags = flags;
- ss->ss_seq = ++(fsdev->nd_seg_sequence);
- ss->ss_create = fsdev->nd_ts.tv_sec;
- nandfs_get_segment_range(fsdev, seg->seg_next, &ss->ss_next, NULL);
- ss->ss_nblocks = seg->nblocks + seg->segsum_blocks;
- ss->ss_nbinfos = seg->nbinfos;
- ss->ss_sumbytes = seg->segsum_bytes;
-
- crc_skip = sizeof(ss->ss_datasum) + sizeof(ss->ss_sumsum);
- blocksize = seg->fsdev->nd_blocksize;
-
- segsum_size = seg->segsum_bytes - crc_skip;
- rest = min(seg->segsum_bytes, blocksize) - crc_skip;
- crc_area = (uint8_t *)ss + crc_skip;
- crc_calc = ~0U;
- while (segsum_size > 0) {
- crc_calc = crc32_raw(crc_area, rest, crc_calc);
- segsum_size -= rest;
- if (!segsum_size)
- break;
- bp = TAILQ_NEXT(bp, b_cluster.cluster_entry);
- crc_area = (uint8_t *)bp->b_data;
- rest = segsum_size <= blocksize ? segsum_size : blocksize;
- }
- ss->ss_sumsum = crc_calc ^ ~0U;
-
- return (ss);
-
-}
-
-static int
-nandfs_save_buf(struct buf *bp, uint64_t blocknr, struct nandfs_device *fsdev)
-{
- struct bufobj *bo;
- int error;
-
- bo = &fsdev->nd_devvp->v_bufobj;
-
- bp->b_blkno = nandfs_block_to_dblock(fsdev, blocknr);
- bp->b_iooffset = dbtob(bp->b_blkno);
-
- KASSERT(bp->b_bufobj != NULL, ("no bufobj for %p", bp));
- if (bp->b_bufobj != bo) {
- BO_LOCK(bp->b_bufobj);
- BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK,
- BO_LOCKPTR(bp->b_bufobj));
- KASSERT(BUF_ISLOCKED(bp), ("Problem with locking buffer"));
- }
-
- DPRINTF(SYNC, ("%s: buf: %p offset %#jx blk %#jx size %#x\n",
- __func__, bp, (uintmax_t)bp->b_offset, (uintmax_t)blocknr,
- fsdev->nd_blocksize));
-
- NANDFS_UNGATHER(bp);
- nandfs_buf_clear(bp, 0xffffffff);
- bp->b_flags &= ~(B_ASYNC|B_INVAL|B_MANAGED);
- error = bwrite(bp);
- if (error) {
- nandfs_error("%s: error:%d when writing buffer:%p\n",
- __func__, error, bp);
- return (error);
- }
- return (error);
-}
-
-static void
-nandfs_clean_buf(struct nandfs_device *fsdev, struct buf *bp)
-{
-
- DPRINTF(SYNC, ("%s: buf: %p\n", __func__, bp));
-
- NANDFS_UNGATHER(bp);
- nandfs_buf_clear(bp, 0xffffffff);
- bp->b_flags &= ~(B_ASYNC|B_INVAL|B_MANAGED);
- nandfs_undirty_buf_fsdev(fsdev, bp);
-}
-
-static void
-nandfs_clean_segblocks(struct nandfs_segment *seg, uint8_t unlock)
-{
- struct nandfs_device *fsdev = seg->fsdev;
- struct nandfs_segment *next_seg;
- struct buf *bp, *tbp, *next_bp;
- struct vnode *vp, *next_vp;
-
- VOP_LOCK(fsdev->nd_devvp, LK_EXCLUSIVE);
- TAILQ_FOREACH_SAFE(bp, &seg->segsum, b_cluster.cluster_entry, tbp) {
- TAILQ_REMOVE(&seg->segsum, bp, b_cluster.cluster_entry);
- nandfs_clean_buf(fsdev, bp);
- }
-
- TAILQ_FOREACH_SAFE(bp, &seg->data, b_cluster.cluster_entry, tbp) {
- TAILQ_REMOVE(&seg->data, bp, b_cluster.cluster_entry);
-
- /*
- * If bp is not super-root and vnode is not currently
- * locked lock it.
- */
- vp = bp->b_vp;
- next_vp = NULL;
- next_bp = TAILQ_NEXT(bp, b_cluster.cluster_entry);
- if (!next_bp) {
- next_seg = LIST_NEXT(seg, seg_link);
- if (next_seg)
- next_bp = TAILQ_FIRST(&next_seg->data);
- }
-
- if (next_bp)
- next_vp = next_bp->b_vp;
-
- nandfs_clean_buf(fsdev, bp);
-
- if (unlock && vp != NULL && next_vp != vp &&
- !NANDFS_SYS_NODE(VTON(vp)->nn_ino))
- vput(vp);
-
- nandfs_dirty_bufs_decrement(fsdev);
- }
-
- VOP_UNLOCK(fsdev->nd_devvp, 0);
-}
-
-static int
-nandfs_save_segblocks(struct nandfs_segment *seg, uint8_t unlock)
-{
- struct nandfs_device *fsdev = seg->fsdev;
- struct nandfs_segment *next_seg;
- struct buf *bp, *tbp, *next_bp;
- struct vnode *vp, *next_vp;
- uint64_t blocknr;
- uint32_t i = 0;
- int error = 0;
-
- VOP_LOCK(fsdev->nd_devvp, LK_EXCLUSIVE);
- TAILQ_FOREACH_SAFE(bp, &seg->segsum, b_cluster.cluster_entry, tbp) {
- TAILQ_REMOVE(&seg->segsum, bp, b_cluster.cluster_entry);
- blocknr = seg->start_block + i;
- error = nandfs_save_buf(bp, blocknr, fsdev);
- if (error) {
- nandfs_error("%s: error saving buf: %p blocknr:%jx\n",
- __func__, bp, (uintmax_t)blocknr);
- goto out;
- }
- i++;
- }
-
- i = 0;
- TAILQ_FOREACH_SAFE(bp, &seg->data, b_cluster.cluster_entry, tbp) {
- TAILQ_REMOVE(&seg->data, bp, b_cluster.cluster_entry);
-
- blocknr = seg->start_block + seg->segsum_blocks + i;
- /*
- * If bp is not super-root and vnode is not currently
- * locked lock it.
- */
- vp = bp->b_vp;
- next_vp = NULL;
- next_bp = TAILQ_NEXT(bp, b_cluster.cluster_entry);
- if (!next_bp) {
- next_seg = LIST_NEXT(seg, seg_link);
- if (next_seg)
- next_bp = TAILQ_FIRST(&next_seg->data);
- }
-
- if (next_bp)
- next_vp = next_bp->b_vp;
-
- error = nandfs_save_buf(bp, blocknr, fsdev);
- if (error) {
- nandfs_error("%s: error saving buf: %p blknr: %jx\n",
- __func__, bp, (uintmax_t)blocknr);
- if (unlock && vp != NULL && next_vp != vp &&
- !NANDFS_SYS_NODE(VTON(vp)->nn_ino))
- vput(vp);
- goto out;
- }
-
- if (unlock && vp != NULL && next_vp != vp &&
- !NANDFS_SYS_NODE(VTON(vp)->nn_ino))
- vput(vp);
-
- i++;
- nandfs_dirty_bufs_decrement(fsdev);
- }
-out:
- if (error) {
- nandfs_clean_segblocks(seg, unlock);
- VOP_UNLOCK(fsdev->nd_devvp, 0);
- return (error);
- }
-
- VOP_UNLOCK(fsdev->nd_devvp, 0);
- return (error);
-}
-
-
-static void
-clean_seginfo(struct nandfs_seginfo *seginfo, uint8_t unlock)
-{
- struct nandfs_segment *seg;
-
- DPRINTF(SYNC, ("%s: seginfo %p\n", __func__, seginfo));
-
- LIST_FOREACH(seg, &seginfo->seg_list, seg_link) {
- nandfs_clean_segblocks(seg, unlock);
- }
-}
-
-static int
-save_seginfo(struct nandfs_seginfo *seginfo, uint8_t unlock)
-{
- struct nandfs_segment *seg;
- struct nandfs_device *fsdev;
- struct nandfs_segment_summary *ss;
- int error = 0;
-
- fsdev = seginfo->fsdev;
-
- DPRINTF(SYNC, ("%s: seginfo %p\n", __func__, seginfo));
-
- LIST_FOREACH(seg, &seginfo->seg_list, seg_link) {
- if (LIST_NEXT(seg, seg_link)) {
- nandfs_fill_segsum(seg, 0);
- error = nandfs_save_segblocks(seg, unlock);
- if (error) {
- nandfs_error("%s: error:%d saving seg:%p\n",
- __func__, error, seg);
- goto out;
- }
- } else {
- ss = nandfs_fill_segsum(seg, 1);
- fsdev->nd_last_segsum = *ss;
- error = nandfs_save_segblocks(seg, unlock);
- if (error) {
- nandfs_error("%s: error:%d saving seg:%p\n",
- __func__, error, seg);
- goto out;
- }
- fsdev->nd_last_cno++;
- fsdev->nd_last_pseg = seg->start_block;
- }
- }
-out:
- if (error)
- clean_seginfo(seginfo, unlock);
- return (error);
-}
-
-static void
-nandfs_invalidate_bufs(struct nandfs_device *fsdev, uint64_t segno)
-{
- uint64_t start, end;
- struct buf *bp, *tbd;
- struct bufobj *bo;
-
- nandfs_get_segment_range(fsdev, segno, &start, &end);
-
- bo = &NTOV(fsdev->nd_gc_node)->v_bufobj;
-
- BO_LOCK(bo);
-restart_locked_gc:
- TAILQ_FOREACH_SAFE(bp, &bo->bo_clean.bv_hd, b_bobufs, tbd) {
- if (!(bp->b_lblkno >= start && bp->b_lblkno <= end))
- continue;
-
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL))
- goto restart_locked_gc;
-
- bremfree(bp);
- bp->b_flags |= (B_INVAL | B_RELBUF);
- bp->b_flags &= ~(B_ASYNC | B_MANAGED);
- BO_UNLOCK(bo);
- brelse(bp);
- BO_LOCK(bo);
- }
- BO_UNLOCK(bo);
-}
-
-/* Process segments marks to free by cleaner */
-static void
-nandfs_process_segments(struct nandfs_device *fsdev)
-{
- uint64_t saved_segment;
- int i;
-
- if (fsdev->nd_free_base) {
- saved_segment = nandfs_get_segnum_of_block(fsdev,
- fsdev->nd_super.s_last_pseg);
- for (i = 0; i < fsdev->nd_free_count; i++) {
- if (fsdev->nd_free_base[i] == NANDFS_NOSEGMENT)
- continue;
- /* Update superblock if clearing segment point by it */
- if (fsdev->nd_free_base[i] == saved_segment) {
- nandfs_write_superblock(fsdev);
- saved_segment = nandfs_get_segnum_of_block(
- fsdev, fsdev->nd_super.s_last_pseg);
- }
- nandfs_invalidate_bufs(fsdev, fsdev->nd_free_base[i]);
- nandfs_clear_segment(fsdev, fsdev->nd_free_base[i]);
- }
-
- free(fsdev->nd_free_base, M_NANDFSTEMP);
- fsdev->nd_free_base = NULL;
- fsdev->nd_free_count = 0;
- }
-}
-
-/* Collect and write dirty buffers */
-int
-nandfs_sync_file(struct vnode *vp)
-{
- struct nandfs_device *fsdev;
- struct nandfs_node *nandfs_node;
- struct nandfsmount *nmp;
- struct nandfs_node *dat, *su, *ifile, *cp;
- struct nandfs_seginfo *seginfo = NULL;
- struct nandfs_segment *seg;
- int update, error;
- int cno_changed;
-
- ASSERT_VOP_LOCKED(vp, __func__);
- DPRINTF(SYNC, ("%s: START\n", __func__));
-
- error = 0;
- nmp = VFSTONANDFS(vp->v_mount);
- fsdev = nmp->nm_nandfsdev;
-
- dat = fsdev->nd_dat_node;
- su = fsdev->nd_su_node;
- cp = fsdev->nd_cp_node;
- ifile = nmp->nm_ifile_node;
-
- NANDFS_WRITEASSERT(fsdev);
- if (lockmgr(&fsdev->nd_seg_const, LK_UPGRADE, NULL) != 0) {
- DPRINTF(SYNC, ("%s: lost shared lock\n", __func__));
- if (lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL) != 0)
- panic("couldn't lock exclusive");
- }
- DPRINTF(SYNC, ("%s: got lock\n", __func__));
-
- VOP_LOCK(NTOV(su), LK_EXCLUSIVE);
- create_seginfo(fsdev, &seginfo);
-
- update = 0;
-
- nandfs_node = VTON(vp);
- if (nandfs_node->nn_flags & IN_MODIFIED) {
- nandfs_node->nn_flags &= ~(IN_MODIFIED);
- update = 1;
- }
-
- if (vp->v_bufobj.bo_dirty.bv_cnt) {
- error = nandfs_iterate_dirty_buf(vp, seginfo, 0);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
- nandfs_error("%s: err:%d iterating dirty bufs vp:%p",
- __func__, error, vp);
- return (error);
- }
- update = 1;
- }
-
- if (update) {
- VOP_LOCK(NTOV(ifile), LK_EXCLUSIVE);
- error = nandfs_node_update(nandfs_node);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- VOP_UNLOCK(NTOV(ifile), 0);
- VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
- nandfs_error("%s: err:%d updating vp:%p",
- __func__, error, vp);
- return (error);
- }
- VOP_UNLOCK(NTOV(ifile), 0);
- }
-
- cno_changed = 0;
- if (seginfo->blocks) {
- VOP_LOCK(NTOV(cp), LK_EXCLUSIVE);
- cno_changed = 1;
- /* Create new checkpoint */
- error = nandfs_get_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- VOP_UNLOCK(NTOV(cp), 0);
- VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
- nandfs_error("%s: err:%d getting cp:%jx",
- __func__, error, fsdev->nd_last_cno + 1);
- return (error);
- }
-
- /* Reiterate all blocks and assign physical block number */
- nandfs_seginfo_assign_pblk(seginfo);
-
- /* Fill checkpoint data */
- error = nandfs_set_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1,
- &ifile->nn_inode, seginfo->blocks);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- VOP_UNLOCK(NTOV(cp), 0);
- VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
- nandfs_error("%s: err:%d setting cp:%jx",
- __func__, error, fsdev->nd_last_cno + 1);
- return (error);
- }
-
- VOP_UNLOCK(NTOV(cp), 0);
- LIST_FOREACH(seg, &seginfo->seg_list, seg_link)
- nandfs_update_segment(fsdev, seg->seg_num,
- seg->nblocks + seg->segsum_blocks);
-
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- error = save_seginfo(seginfo, 0);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- VOP_UNLOCK(NTOV(dat), 0);
- VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
- nandfs_error("%s: err:%d updating seg",
- __func__, error);
- return (error);
- }
- VOP_UNLOCK(NTOV(dat), 0);
- }
-
- VOP_UNLOCK(NTOV(su), 0);
-
- delete_seginfo(seginfo);
- lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
-
- if (cno_changed && !error) {
- if (nandfs_cps_between_sblocks != 0 &&
- fsdev->nd_last_cno % nandfs_cps_between_sblocks == 0)
- nandfs_write_superblock(fsdev);
- }
-
- ASSERT_VOP_LOCKED(vp, __func__);
- DPRINTF(SYNC, ("%s: END error %d\n", __func__, error));
- return (error);
-}
-
-int
-nandfs_segment_constructor(struct nandfsmount *nmp, int flags)
-{
- struct nandfs_device *fsdev;
- struct nandfs_seginfo *seginfo = NULL;
- struct nandfs_segment *seg;
- struct nandfs_node *dat, *su, *ifile, *cp, *gc;
- int cno_changed, error;
-
- DPRINTF(SYNC, ("%s: START\n", __func__));
- fsdev = nmp->nm_nandfsdev;
-
- lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL);
- DPRINTF(SYNC, ("%s: git lock\n", __func__));
-again:
- create_seginfo(fsdev, &seginfo);
-
- dat = fsdev->nd_dat_node;
- su = fsdev->nd_su_node;
- cp = fsdev->nd_cp_node;
- gc = fsdev->nd_gc_node;
- ifile = nmp->nm_ifile_node;
-
- VOP_LOCK(NTOV(su), LK_EXCLUSIVE);
- VOP_LOCK(NTOV(ifile), LK_EXCLUSIVE);
- VOP_LOCK(NTOV(gc), LK_EXCLUSIVE);
- VOP_LOCK(NTOV(cp), LK_EXCLUSIVE);
-
- nandfs_iterate_system_vnode(gc, seginfo);
- nandfs_iterate_dirty_vnodes(nmp->nm_vfs_mountp, seginfo);
- nandfs_iterate_system_vnode(ifile, seginfo);
- nandfs_iterate_system_vnode(su, seginfo);
-
- cno_changed = 0;
- if (seginfo->blocks || flags) {
- cno_changed = 1;
- /* Create new checkpoint */
- error = nandfs_get_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- goto error_locks;
- }
-
- /* Collect blocks from system files */
- nandfs_iterate_system_vnode(cp, seginfo);
- nandfs_iterate_system_vnode(su, seginfo);
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- nandfs_iterate_system_vnode(dat, seginfo);
- VOP_UNLOCK(NTOV(dat), 0);
-reiterate:
- seginfo->reiterate = 0;
- nandfs_iterate_system_vnode(su, seginfo);
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- nandfs_iterate_system_vnode(dat, seginfo);
- VOP_UNLOCK(NTOV(dat), 0);
- if (seginfo->reiterate)
- goto reiterate;
- if (!(seginfo->curseg) || !seginfo->curseg->num_blocks) {
- error = create_segment(seginfo);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- goto error_locks;
- }
- goto reiterate;
- }
-
- /* Reiterate all blocks and assign physical block number */
- nandfs_seginfo_assign_pblk(seginfo);
-
- /* Fill superroot */
- error = nandfs_add_superroot(seginfo);
- if (error) {
- clean_seginfo(seginfo, 0);
- delete_seginfo(seginfo);
- goto error_locks;
- }
- KASSERT(!(seginfo->reiterate), ("reiteration after superroot"));
-
- /* Fill checkpoint data */
- nandfs_set_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1,
- &ifile->nn_inode, seginfo->blocks);
-
- LIST_FOREACH(seg, &seginfo->seg_list, seg_link)
- nandfs_update_segment(fsdev, seg->seg_num,
- seg->nblocks + seg->segsum_blocks);
-
- VOP_LOCK(NTOV(dat), LK_EXCLUSIVE);
- error = save_seginfo(seginfo, 1);
- if (error) {
- clean_seginfo(seginfo, 1);
- delete_seginfo(seginfo);
- goto error_dat;
- }
- VOP_UNLOCK(NTOV(dat), 0);
- }
-
- VOP_UNLOCK(NTOV(cp), 0);
- VOP_UNLOCK(NTOV(gc), 0);
- VOP_UNLOCK(NTOV(ifile), 0);
-
- nandfs_process_segments(fsdev);
-
- VOP_UNLOCK(NTOV(su), 0);
-
- delete_seginfo(seginfo);
-
- /*
- * XXX: a hack, will go away soon
- */
- if ((NTOV(dat)->v_bufobj.bo_dirty.bv_cnt != 0 ||
- NTOV(cp)->v_bufobj.bo_dirty.bv_cnt != 0 ||
- NTOV(gc)->v_bufobj.bo_dirty.bv_cnt != 0 ||
- NTOV(ifile)->v_bufobj.bo_dirty.bv_cnt != 0 ||
- NTOV(su)->v_bufobj.bo_dirty.bv_cnt != 0) &&
- (flags & NANDFS_UMOUNT)) {
- DPRINTF(SYNC, ("%s: RERUN\n", __func__));
- goto again;
- }
-
- MPASS(fsdev->nd_free_base == NULL);
-
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
-
- if (cno_changed) {
- if ((nandfs_cps_between_sblocks != 0 &&
- fsdev->nd_last_cno % nandfs_cps_between_sblocks == 0) ||
- flags & NANDFS_UMOUNT)
- nandfs_write_superblock(fsdev);
- }
-
- DPRINTF(SYNC, ("%s: END\n", __func__));
- return (0);
-error_dat:
- VOP_UNLOCK(NTOV(dat), 0);
-error_locks:
- VOP_UNLOCK(NTOV(cp), 0);
- VOP_UNLOCK(NTOV(gc), 0);
- VOP_UNLOCK(NTOV(ifile), 0);
- VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
-
- return (error);
-}
-
-#ifdef DDB
-/*
- * Show details about the given NANDFS mount point.
- */
-DB_SHOW_COMMAND(nandfs, db_show_nandfs)
-{
- struct mount *mp;
- struct nandfs_device *nffsdev;
- struct nandfs_segment *seg;
- struct nandfsmount *nmp;
- struct buf *bp;
- struct vnode *vp;
-
- if (!have_addr) {
- db_printf("\nUsage: show nandfs <mount_addr>\n");
- return;
- }
-
- mp = (struct mount *)addr;
- db_printf("%p %s on %s (%s)\n", mp, mp->mnt_stat.f_mntfromname,
- mp->mnt_stat.f_mntonname, mp->mnt_stat.f_fstypename);
-
-
- nmp = (struct nandfsmount *)(mp->mnt_data);
- nffsdev = nmp->nm_nandfsdev;
- db_printf("dev vnode:%p\n", nffsdev->nd_devvp);
- db_printf("blocksize:%jx last cno:%jx last pseg:%jx seg num:%jx\n",
- (uintmax_t)nffsdev->nd_blocksize, (uintmax_t)nffsdev->nd_last_cno,
- (uintmax_t)nffsdev->nd_last_pseg, (uintmax_t)nffsdev->nd_seg_num);
- db_printf("system nodes: dat:%p cp:%p su:%p ifile:%p gc:%p\n",
- nffsdev->nd_dat_node, nffsdev->nd_cp_node, nffsdev->nd_su_node,
- nmp->nm_ifile_node, nffsdev->nd_gc_node);
-
- if (nffsdev->nd_seginfo != NULL) {
- LIST_FOREACH(seg, &nffsdev->nd_seginfo->seg_list, seg_link) {
- db_printf("seg: %p\n", seg);
- TAILQ_FOREACH(bp, &seg->segsum,
- b_cluster.cluster_entry)
- db_printf("segbp %p\n", bp);
- TAILQ_FOREACH(bp, &seg->data,
- b_cluster.cluster_entry) {
- vp = bp->b_vp;
- db_printf("bp:%p bp->b_vp:%p ino:%jx\n", bp, vp,
- (uintmax_t)(vp ? VTON(vp)->nn_ino : 0));
- }
- }
- }
-}
-#endif
diff --git a/sys/fs/nandfs/nandfs_subr.c b/sys/fs/nandfs/nandfs_subr.c
deleted file mode 100644
index 0a3f65a50543..000000000000
--- a/sys/fs/nandfs/nandfs_subr.c
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/gsb_crc32.h>
-#include <sys/namei.h>
-#include <sys/resourcevar.h>
-#include <sys/kernel.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/signalvar.h>
-#include <sys/malloc.h>
-#include <sys/dirent.h>
-#include <sys/lockf.h>
-#include <sys/libkern.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include <machine/_inttypes.h>
-#include "nandfs_mount.h"
-#include "nandfs.h"
-#include "nandfs_subr.h"
-
-MALLOC_DEFINE(M_NANDFSMNT, "nandfs_mount", "NANDFS mount");
-MALLOC_DEFINE(M_NANDFSTEMP, "nandfs_tmt", "NANDFS tmp");
-
-uma_zone_t nandfs_node_zone;
-
-void nandfs_bdflush(struct bufobj *bo, struct buf *bp);
-int nandfs_bufsync(struct bufobj *bo, int waitfor);
-
-struct buf_ops buf_ops_nandfs = {
- .bop_name = "buf_ops_nandfs",
- .bop_write = bufwrite,
- .bop_strategy = bufstrategy,
- .bop_sync = nandfs_bufsync,
- .bop_bdflush = nandfs_bdflush,
-};
-
-int
-nandfs_bufsync(struct bufobj *bo, int waitfor)
-{
- struct vnode *vp;
- int error = 0;
-
- vp = bo2vnode(bo);
-
- ASSERT_VOP_LOCKED(vp, __func__);
- error = nandfs_sync_file(vp);
- if (error)
- nandfs_warning("%s: cannot flush buffers err:%d\n",
- __func__, error);
-
- return (error);
-}
-
-void
-nandfs_bdflush(bo, bp)
- struct bufobj *bo;
- struct buf *bp;
-{
- struct vnode *vp;
- int error;
-
- if (bo->bo_dirty.bv_cnt <= ((dirtybufthresh * 8) / 10))
- return;
-
- vp = bp->b_vp;
- if (NANDFS_SYS_NODE(VTON(vp)->nn_ino))
- return;
-
- if (NANDFS_IS_INDIRECT(bp))
- return;
-
- error = nandfs_sync_file(vp);
- if (error)
- nandfs_warning("%s: cannot flush buffers err:%d\n",
- __func__, error);
-}
-
-int
-nandfs_init(struct vfsconf *vfsp)
-{
-
- nandfs_node_zone = uma_zcreate("nandfs node zone",
- sizeof(struct nandfs_node), NULL, NULL, NULL, NULL, 0, 0);
-
- return (0);
-}
-
-int
-nandfs_uninit(struct vfsconf *vfsp)
-{
-
- uma_zdestroy(nandfs_node_zone);
- return (0);
-}
-
-/* Basic calculators */
-uint64_t
-nandfs_get_segnum_of_block(struct nandfs_device *nandfsdev,
- nandfs_daddr_t blocknr)
-{
- uint64_t segnum, blks_per_seg;
-
- MPASS(blocknr >= nandfsdev->nd_fsdata.f_first_data_block);
-
- blks_per_seg = nandfsdev->nd_fsdata.f_blocks_per_segment;
-
- segnum = blocknr / blks_per_seg;
- segnum -= nandfsdev->nd_fsdata.f_first_data_block / blks_per_seg;
-
- DPRINTF(SYNC, ("%s: returning blocknr %jx -> segnum %jx\n", __func__,
- blocknr, segnum));
-
- return (segnum);
-}
-
-void
-nandfs_get_segment_range(struct nandfs_device *nandfsdev, uint64_t segnum,
- uint64_t *seg_start, uint64_t *seg_end)
-{
- uint64_t blks_per_seg;
-
- blks_per_seg = nandfsdev->nd_fsdata.f_blocks_per_segment;
- *seg_start = nandfsdev->nd_fsdata.f_first_data_block +
- blks_per_seg * segnum;
- if (seg_end != NULL)
- *seg_end = *seg_start + blks_per_seg -1;
-}
-
-void nandfs_calc_mdt_consts(struct nandfs_device *nandfsdev,
- struct nandfs_mdt *mdt, int entry_size)
-{
- uint32_t blocksize = nandfsdev->nd_blocksize;
-
- mdt->entries_per_group = blocksize * 8;
- mdt->entries_per_block = blocksize / entry_size;
-
- mdt->blocks_per_group =
- (mdt->entries_per_group -1) / mdt->entries_per_block + 1 + 1;
- mdt->groups_per_desc_block =
- blocksize / sizeof(struct nandfs_block_group_desc);
- mdt->blocks_per_desc_block =
- mdt->groups_per_desc_block * mdt->blocks_per_group + 1;
-}
-
-int
-nandfs_dev_bread(struct nandfs_device *nandfsdev, nandfs_lbn_t blocknr,
- struct ucred *cred, int flags, struct buf **bpp)
-{
- int blk2dev = nandfsdev->nd_blocksize / DEV_BSIZE;
- int error;
-
- DPRINTF(BLOCK, ("%s: read from block %jx vp %p\n", __func__,
- blocknr * blk2dev, nandfsdev->nd_devvp));
- error = bread(nandfsdev->nd_devvp, blocknr * blk2dev,
- nandfsdev->nd_blocksize, NOCRED, bpp);
- if (error)
- nandfs_error("%s: cannot read from device - blk:%jx\n",
- __func__, blocknr);
- return (error);
-}
-
-/* Read on a node */
-int
-nandfs_bread(struct nandfs_node *node, nandfs_lbn_t blocknr,
- struct ucred *cred, int flags, struct buf **bpp)
-{
- nandfs_daddr_t vblk;
- int error;
-
- DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node),
- blocknr));
-
- error = bread(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize,
- cred, bpp);
-
- KASSERT(error == 0, ("%s: vp:%p lbn:%#jx err:%d\n", __func__,
- NTOV(node), blocknr, error));
-
- if (!nandfs_vblk_get(*bpp) &&
- ((*bpp)->b_flags & B_CACHE) && node->nn_ino != NANDFS_DAT_INO) {
- nandfs_bmap_lookup(node, blocknr, &vblk);
- nandfs_vblk_set(*bpp, vblk);
- }
- return (error);
-}
-
-int
-nandfs_bread_meta(struct nandfs_node *node, nandfs_lbn_t blocknr,
- struct ucred *cred, int flags, struct buf **bpp)
-{
- nandfs_daddr_t vblk;
- int error;
-
- DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node),
- blocknr));
-
- error = bread(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize,
- cred, bpp);
-
- KASSERT(error == 0, ("%s: vp:%p lbn:%#jx err:%d\n", __func__,
- NTOV(node), blocknr, error));
-
- if (!nandfs_vblk_get(*bpp) &&
- ((*bpp)->b_flags & B_CACHE) && node->nn_ino != NANDFS_DAT_INO) {
- nandfs_bmap_lookup(node, blocknr, &vblk);
- nandfs_vblk_set(*bpp, vblk);
- }
-
- return (error);
-}
-
-int
-nandfs_bdestroy(struct nandfs_node *node, nandfs_daddr_t vblk)
-{
- int error;
-
- if (!NANDFS_SYS_NODE(node->nn_ino))
- NANDFS_WRITEASSERT(node->nn_nandfsdev);
-
- error = nandfs_vblock_end(node->nn_nandfsdev, vblk);
- if (error) {
- nandfs_error("%s: ending vblk: %jx failed\n",
- __func__, (uintmax_t)vblk);
- return (error);
- }
- node->nn_inode.i_blocks--;
-
- return (0);
-}
-
-int
-nandfs_bcreate(struct nandfs_node *node, nandfs_lbn_t blocknr,
- struct ucred *cred, int flags, struct buf **bpp)
-{
- int error;
-
- ASSERT_VOP_LOCKED(NTOV(node), __func__);
- if (!NANDFS_SYS_NODE(node->nn_ino))
- NANDFS_WRITEASSERT(node->nn_nandfsdev);
-
- DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node),
- blocknr));
-
- *bpp = getblk(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize,
- 0, 0, 0);
-
- KASSERT((*bpp), ("%s: vp:%p lbn:%#jx\n", __func__,
- NTOV(node), blocknr));
-
- if (*bpp) {
- vfs_bio_clrbuf(*bpp);
- (*bpp)->b_blkno = ~(0); /* To avoid VOP_BMAP in bdwrite */
- error = nandfs_bmap_insert_block(node, blocknr, *bpp);
- if (error) {
- nandfs_warning("%s: failed bmap insert node:%p"
- " blk:%jx\n", __func__, node, blocknr);
- brelse(*bpp);
- return (error);
- }
- node->nn_inode.i_blocks++;
-
- return (0);
- }
-
- return (-1);
-}
-
-int
-nandfs_bcreate_meta(struct nandfs_node *node, nandfs_lbn_t blocknr,
- struct ucred *cred, int flags, struct buf **bpp)
-{
- struct nandfs_device *fsdev;
- nandfs_daddr_t vblk;
- int error;
-
- ASSERT_VOP_LOCKED(NTOV(node), __func__);
- NANDFS_WRITEASSERT(node->nn_nandfsdev);
-
- DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node),
- blocknr));
-
- fsdev = node->nn_nandfsdev;
-
- *bpp = getblk(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize,
- 0, 0, 0);
-
- KASSERT((*bpp), ("%s: vp:%p lbn:%#jx\n", __func__,
- NTOV(node), blocknr));
-
- memset((*bpp)->b_data, 0, fsdev->nd_blocksize);
-
- vfs_bio_clrbuf(*bpp);
- (*bpp)->b_blkno = ~(0); /* To avoid VOP_BMAP in bdwrite */
-
- nandfs_buf_set(*bpp, NANDFS_VBLK_ASSIGNED);
-
- if (node->nn_ino != NANDFS_DAT_INO) {
- error = nandfs_vblock_alloc(fsdev, &vblk);
- if (error) {
- nandfs_buf_clear(*bpp, NANDFS_VBLK_ASSIGNED);
- brelse(*bpp);
- return (error);
- }
- } else
- vblk = fsdev->nd_fakevblk++;
-
- nandfs_vblk_set(*bpp, vblk);
-
- nandfs_bmap_insert_block(node, blocknr, *bpp);
- return (0);
-}
-
-/* Translate index to a file block number and an entry */
-void
-nandfs_mdt_trans(struct nandfs_mdt *mdt, uint64_t index,
- nandfs_lbn_t *blocknr, uint32_t *entry_in_block)
-{
- uint64_t blknr;
- uint64_t group, group_offset, blocknr_in_group;
- uint64_t desc_block, desc_offset;
-
- /* Calculate our offset in the file */
- group = index / mdt->entries_per_group;
- group_offset = index % mdt->entries_per_group;
- desc_block = group / mdt->groups_per_desc_block;
- desc_offset = group % mdt->groups_per_desc_block;
- blocknr_in_group = group_offset / mdt->entries_per_block;
-
- /* To descgroup offset */
- blknr = 1 + desc_block * mdt->blocks_per_desc_block;
-
- /* To group offset */
- blknr += desc_offset * mdt->blocks_per_group;
-
- /* To actual file block */
- blknr += 1 + blocknr_in_group;
-
- *blocknr = blknr;
- *entry_in_block = group_offset % mdt->entries_per_block;
-}
-
-void
-nandfs_mdt_trans_blk(struct nandfs_mdt *mdt, uint64_t index,
- uint64_t *desc, uint64_t *bitmap, nandfs_lbn_t *blocknr,
- uint32_t *entry_in_block)
-{
- uint64_t blknr;
- uint64_t group, group_offset, blocknr_in_group;
- uint64_t desc_block, desc_offset;
-
- /* Calculate our offset in the file */
- group = index / mdt->entries_per_group;
- group_offset = index % mdt->entries_per_group;
- desc_block = group / mdt->groups_per_desc_block;
- desc_offset = group % mdt->groups_per_desc_block;
- blocknr_in_group = group_offset / mdt->entries_per_block;
-
- /* To descgroup offset */
- *desc = desc_block * mdt->blocks_per_desc_block;
- blknr = 1 + desc_block * mdt->blocks_per_desc_block;
-
- /* To group offset */
- blknr += desc_offset * mdt->blocks_per_group;
- *bitmap = blknr;
-
- /* To actual file block */
- blknr += 1 + blocknr_in_group;
-
- *blocknr = blknr;
- *entry_in_block = group_offset % mdt->entries_per_block;
-
- DPRINTF(ALLOC,
- ("%s: desc_buf: %jx bitmap_buf: %jx entry_buf: %jx entry: %x\n",
- __func__, (uintmax_t)*desc, (uintmax_t)*bitmap,
- (uintmax_t)*blocknr, *entry_in_block));
-}
-
-int
-nandfs_vtop(struct nandfs_node *node, nandfs_daddr_t vblocknr,
- nandfs_daddr_t *pblocknr)
-{
- struct nandfs_node *dat_node;
- struct nandfs_dat_entry *entry;
- struct buf *bp;
- nandfs_lbn_t ldatblknr;
- uint32_t entry_in_block;
- int locked, error;
-
- if (node->nn_ino == NANDFS_DAT_INO || node->nn_ino == NANDFS_GC_INO) {
- *pblocknr = vblocknr;
- return (0);
- }
-
- /* only translate valid vblocknrs */
- if (vblocknr == 0)
- return (0);
-
- dat_node = node->nn_nandfsdev->nd_dat_node;
- nandfs_mdt_trans(&node->nn_nandfsdev->nd_dat_mdt, vblocknr, &ldatblknr,
- &entry_in_block);
-
- locked = NANDFS_VOP_ISLOCKED(NTOV(dat_node));
- if (!locked)
- VOP_LOCK(NTOV(dat_node), LK_SHARED);
- error = nandfs_bread(dat_node, ldatblknr, NOCRED, 0, &bp);
- if (error) {
- DPRINTF(TRANSLATE, ("vtop: can't read in DAT block %#jx!\n",
- (uintmax_t)ldatblknr));
- brelse(bp);
- VOP_UNLOCK(NTOV(dat_node), 0);
- return (error);
- }
-
- /* Get our translation */
- entry = ((struct nandfs_dat_entry *) bp->b_data) + entry_in_block;
- DPRINTF(TRANSLATE, ("\tentry %p data %p entry_in_block %x\n",
- entry, bp->b_data, entry_in_block))
- DPRINTF(TRANSLATE, ("\tvblk %#jx -> %#jx for cp [%#jx-%#jx]\n",
- (uintmax_t)vblocknr, (uintmax_t)entry->de_blocknr,
- (uintmax_t)entry->de_start, (uintmax_t)entry->de_end));
-
- *pblocknr = entry->de_blocknr;
- brelse(bp);
- if (!locked)
- VOP_UNLOCK(NTOV(dat_node), 0);
-
- MPASS(*pblocknr >= node->nn_nandfsdev->nd_fsdata.f_first_data_block ||
- *pblocknr == 0);
-
- return (0);
-}
-
-int
-nandfs_segsum_valid(struct nandfs_segment_summary *segsum)
-{
-
- return (segsum->ss_magic == NANDFS_SEGSUM_MAGIC);
-}
-
-int
-nandfs_load_segsum(struct nandfs_device *fsdev, nandfs_daddr_t blocknr,
- struct nandfs_segment_summary *segsum)
-{
- struct buf *bp;
- int error;
-
- DPRINTF(VOLUMES, ("nandfs: try segsum at block %jx\n",
- (uintmax_t)blocknr));
-
- error = nandfs_dev_bread(fsdev, blocknr, NOCRED, 0, &bp);
- if (error)
- return (error);
-
- memcpy(segsum, bp->b_data, sizeof(struct nandfs_segment_summary));
- brelse(bp);
-
- if (!nandfs_segsum_valid(segsum)) {
- DPRINTF(VOLUMES, ("%s: bad magic pseg:%jx\n", __func__,
- blocknr));
- return (EINVAL);
- }
-
- return (error);
-}
-
-static int
-nandfs_load_super_root(struct nandfs_device *nandfsdev,
- struct nandfs_segment_summary *segsum, uint64_t pseg)
-{
- struct nandfs_super_root super_root;
- struct buf *bp;
- uint64_t blocknr;
- uint32_t super_root_crc, comp_crc;
- int off, error;
-
- /* Check if there is a superroot */
- if ((segsum->ss_flags & NANDFS_SS_SR) == 0) {
- DPRINTF(VOLUMES, ("%s: no super root in pseg:%jx\n", __func__,
- pseg));
- return (ENOENT);
- }
-
- /* Get our super root, located at the end of the pseg */
- blocknr = pseg + segsum->ss_nblocks - 1;
- DPRINTF(VOLUMES, ("%s: try at %#jx\n", __func__, (uintmax_t)blocknr));
-
- error = nandfs_dev_bread(nandfsdev, blocknr, NOCRED, 0, &bp);
- if (error)
- return (error);
-
- memcpy(&super_root, bp->b_data, sizeof(struct nandfs_super_root));
- brelse(bp);
-
- /* Check super root CRC */
- super_root_crc = super_root.sr_sum;
- off = sizeof(super_root.sr_sum);
- comp_crc = crc32((uint8_t *)&super_root + off,
- NANDFS_SR_BYTES - off);
-
- if (super_root_crc != comp_crc) {
- DPRINTF(VOLUMES, ("%s: invalid crc:%#x [expect:%#x]\n",
- __func__, super_root_crc, comp_crc));
- return (EINVAL);
- }
-
- nandfsdev->nd_super_root = super_root;
- DPRINTF(VOLUMES, ("%s: got valid superroot\n", __func__));
-
- return (0);
-}
-
-/*
- * Search for the last super root recorded.
- */
-int
-nandfs_search_super_root(struct nandfs_device *nandfsdev)
-{
- struct nandfs_super_block *super;
- struct nandfs_segment_summary segsum;
- uint64_t seg_start, seg_end, cno, seq, create, pseg;
- uint64_t segnum;
- int error, found;
-
- error = found = 0;
-
- /* Search for last super root */
- pseg = nandfsdev->nd_super.s_last_pseg;
- segnum = nandfs_get_segnum_of_block(nandfsdev, pseg);
-
- cno = nandfsdev->nd_super.s_last_cno;
- create = seq = 0;
- DPRINTF(VOLUMES, ("%s: start in pseg %#jx\n", __func__,
- (uintmax_t)pseg));
-
- for (;;) {
- error = nandfs_load_segsum(nandfsdev, pseg, &segsum);
- if (error)
- break;
-
- if (segsum.ss_seq < seq || segsum.ss_create < create)
- break;
-
- /* Try to load super root */
- if (segsum.ss_flags & NANDFS_SS_SR) {
- error = nandfs_load_super_root(nandfsdev, &segsum, pseg);
- if (error)
- break; /* confused */
- found = 1;
-
- super = &nandfsdev->nd_super;
- nandfsdev->nd_last_segsum = segsum;
- super->s_last_pseg = pseg;
- super->s_last_cno = cno++;
- super->s_last_seq = segsum.ss_seq;
- super->s_state = NANDFS_VALID_FS;
- seq = segsum.ss_seq;
- create = segsum.ss_create;
- } else {
- seq = segsum.ss_seq;
- create = segsum.ss_create;
- }
-
- /* Calculate next partial segment location */
- pseg += segsum.ss_nblocks;
- DPRINTF(VOLUMES, ("%s: next partial seg is %jx\n", __func__,
- (uintmax_t)pseg));
-
- /* Did we reach the end of the segment? if so, go to the next */
- nandfs_get_segment_range(nandfsdev, segnum, &seg_start,
- &seg_end);
- if (pseg >= seg_end) {
- pseg = segsum.ss_next;
- DPRINTF(VOLUMES,
- (" partial seg oor next is %jx[%jx - %jx]\n",
- (uintmax_t)pseg, (uintmax_t)seg_start,
- (uintmax_t)seg_end));
- }
- segnum = nandfs_get_segnum_of_block(nandfsdev, pseg);
- }
-
- if (error && !found)
- return (error);
-
- return (0);
-}
-
-int
-nandfs_get_node_raw(struct nandfs_device *nandfsdev, struct nandfsmount *nmp,
- uint64_t ino, struct nandfs_inode *inode, struct nandfs_node **nodep)
-{
- struct nandfs_node *node;
- struct vnode *nvp;
- struct mount *mp;
- int error;
-
- *nodep = NULL;
-
- /* Associate with mountpoint if present */
- if (nmp) {
- mp = nmp->nm_vfs_mountp;
- error = getnewvnode("nandfs", mp, &nandfs_vnodeops, &nvp);
- if (error)
- return (error);
- } else {
- mp = NULL;
- error = getnewvnode("snandfs", mp, &nandfs_system_vnodeops,
- &nvp);
- if (error)
- return (error);
- }
-
- if (mp)
- NANDFS_WRITELOCK(nandfsdev);
-
- DPRINTF(IFILE, ("%s: ino: %#jx -> vp: %p\n",
- __func__, (uintmax_t)ino, nvp));
- /* Lock node */
- lockmgr(nvp->v_vnlock, LK_EXCLUSIVE, NULL);
-
- if (mp) {
- error = insmntque(nvp, mp);
- if (error != 0) {
- *nodep = NULL;
- return (error);
- }
- }
-
- node = uma_zalloc(nandfs_node_zone, M_WAITOK | M_ZERO);
-
- /* Crosslink */
- node->nn_vnode = nvp;
- nvp->v_bufobj.bo_ops = &buf_ops_nandfs;
- node->nn_nmp = nmp;
- node->nn_nandfsdev = nandfsdev;
- nvp->v_data = node;
-
- /* Initiase NANDFS node */
- node->nn_ino = ino;
- if (inode != NULL)
- node->nn_inode = *inode;
-
- nandfs_vinit(nvp, ino);
-
- /* Return node */
- *nodep = node;
- DPRINTF(IFILE, ("%s: ino:%#jx vp:%p node:%p\n",
- __func__, (uintmax_t)ino, nvp, *nodep));
-
- return (0);
-}
-
-int
-nandfs_get_node(struct nandfsmount *nmp, uint64_t ino,
- struct nandfs_node **nodep)
-{
- struct nandfs_device *nandfsdev;
- struct nandfs_inode inode, *entry;
- struct vnode *nvp, *vpp;
- struct thread *td;
- struct buf *bp;
- uint64_t ivblocknr;
- uint32_t entry_in_block;
- int error;
-
- /* Look up node in hash table */
- td = curthread;
- *nodep = NULL;
-
- if ((ino < NANDFS_ATIME_INO) && (ino != NANDFS_ROOT_INO)) {
- printf("nandfs_get_node: system ino %"PRIu64" not in mount "
- "point!\n", ino);
- return (ENOENT);
- }
-
- error = vfs_hash_get(nmp->nm_vfs_mountp, ino, LK_EXCLUSIVE, td, &nvp,
- NULL, NULL);
- if (error)
- return (error);
-
- if (nvp != NULL) {
- *nodep = (struct nandfs_node *)nvp->v_data;
- return (0);
- }
-
- /* Look up inode structure in mountpoints ifile */
- nandfsdev = nmp->nm_nandfsdev;
- nandfs_mdt_trans(&nandfsdev->nd_ifile_mdt, ino, &ivblocknr,
- &entry_in_block);
-
- VOP_LOCK(NTOV(nmp->nm_ifile_node), LK_SHARED);
- error = nandfs_bread(nmp->nm_ifile_node, ivblocknr, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- VOP_UNLOCK(NTOV(nmp->nm_ifile_node), 0);
- return (ENOENT);
- }
-
- /* Get inode entry */
- entry = (struct nandfs_inode *) bp->b_data + entry_in_block;
- memcpy(&inode, entry, sizeof(struct nandfs_inode));
- brelse(bp);
- VOP_UNLOCK(NTOV(nmp->nm_ifile_node), 0);
-
- /* Get node */
- error = nandfs_get_node_raw(nmp->nm_nandfsdev, nmp, ino, &inode, nodep);
- if (error) {
- *nodep = NULL;
- return (error);
- }
-
- nvp = (*nodep)->nn_vnode;
- error = vfs_hash_insert(nvp, ino, 0, td, &vpp, NULL, NULL);
- if (error) {
- *nodep = NULL;
- return (error);
- }
-
- return (error);
-}
-
-void
-nandfs_dispose_node(struct nandfs_node **nodep)
-{
- struct nandfs_node *node;
- struct vnode *vp;
-
- /* Protect against rogue values */
- node = *nodep;
- if (!node) {
- return;
- }
- DPRINTF(NODE, ("nandfs_dispose_node: %p\n", *nodep));
-
- vp = NTOV(node);
- vp->v_data = NULL;
-
- /* Free our associated memory */
- uma_zfree(nandfs_node_zone, node);
-
- *nodep = NULL;
-}
-
-int
-nandfs_lookup_name_in_dir(struct vnode *dvp, const char *name, int namelen,
- uint64_t *ino, int *found, uint64_t *off)
-{
- struct nandfs_node *dir_node = VTON(dvp);
- struct nandfs_dir_entry *ndirent;
- struct buf *bp;
- uint64_t file_size, diroffset, blkoff;
- uint64_t blocknr;
- uint32_t blocksize = dir_node->nn_nandfsdev->nd_blocksize;
- uint8_t *pos, name_len;
- int error;
-
- *found = 0;
-
- DPRINTF(VNCALL, ("%s: %s file\n", __func__, name));
- if (dvp->v_type != VDIR) {
- return (ENOTDIR);
- }
-
- /* Get directory filesize */
- file_size = dir_node->nn_inode.i_size;
-
- /* Walk the directory */
- diroffset = 0;
- blocknr = 0;
- blkoff = 0;
- error = nandfs_bread(dir_node, blocknr, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (EIO);
- }
-
- while (diroffset < file_size) {
- if (blkoff >= blocksize) {
- blkoff = 0; blocknr++;
- brelse(bp);
- error = nandfs_bread(dir_node, blocknr, NOCRED, 0,
- &bp);
- if (error) {
- brelse(bp);
- return (EIO);
- }
- }
-
- /* Read in one dirent */
- pos = (uint8_t *) bp->b_data + blkoff;
- ndirent = (struct nandfs_dir_entry *) pos;
- name_len = ndirent->name_len;
-
- if ((name_len == namelen) &&
- (strncmp(name, ndirent->name, name_len) == 0) &&
- (ndirent->inode != 0)) {
- *ino = ndirent->inode;
- *off = diroffset;
- DPRINTF(LOOKUP, ("found `%.*s` with ino %"PRIx64"\n",
- name_len, ndirent->name, *ino));
- *found = 1;
- break;
- }
-
- /* Advance */
- diroffset += ndirent->rec_len;
- blkoff += ndirent->rec_len;
- }
- brelse(bp);
-
- return (error);
-}
-
-int
-nandfs_get_fsinfo(struct nandfsmount *nmp, struct nandfs_fsinfo *fsinfo)
-{
- struct nandfs_device *fsdev;
-
- fsdev = nmp->nm_nandfsdev;
-
- memcpy(&fsinfo->fs_fsdata, &fsdev->nd_fsdata, sizeof(fsdev->nd_fsdata));
- memcpy(&fsinfo->fs_super, &fsdev->nd_super, sizeof(fsdev->nd_super));
- snprintf(fsinfo->fs_dev, sizeof(fsinfo->fs_dev),
- "%s", nmp->nm_vfs_mountp->mnt_stat.f_mntfromname);
-
- return (0);
-}
-
-void
-nandfs_inode_init(struct nandfs_inode *inode, uint16_t mode)
-{
- struct timespec ts;
-
- vfs_timestamp(&ts);
-
- inode->i_blocks = 0;
- inode->i_size = 0;
- inode->i_ctime = ts.tv_sec;
- inode->i_ctime_nsec = ts.tv_nsec;
- inode->i_mtime = ts.tv_sec;
- inode->i_mtime_nsec = ts.tv_nsec;
- inode->i_mode = mode;
- inode->i_links_count = 1;
- if (S_ISDIR(mode))
- inode->i_links_count = 2;
- inode->i_flags = 0;
-
- inode->i_special = 0;
- memset(inode->i_db, 0, sizeof(inode->i_db));
- memset(inode->i_ib, 0, sizeof(inode->i_ib));
-}
-
-void
-nandfs_inode_destroy(struct nandfs_inode *inode)
-{
-
- MPASS(inode->i_blocks == 0);
- bzero(inode, sizeof(*inode));
-}
-
-int
-nandfs_fs_full(struct nandfs_device *nffsdev)
-{
- uint64_t space, bps;
-
- bps = nffsdev->nd_fsdata.f_blocks_per_segment;
- space = (nffsdev->nd_clean_segs - 1) * bps;
-
- DPRINTF(BUF, ("%s: bufs:%jx space:%jx\n", __func__,
- (uintmax_t)nffsdev->nd_dirty_bufs, (uintmax_t)space));
-
- if (nffsdev->nd_dirty_bufs + (nffsdev->nd_segs_reserved * bps) >= space)
- return (1);
-
- return (0);
-}
-
-static int
-_nandfs_dirty_buf(struct buf *bp, int dirty_meta, int force)
-{
- struct nandfs_device *nffsdev;
- struct nandfs_node *node;
- uint64_t ino, bps;
-
- if (NANDFS_ISGATHERED(bp)) {
- bqrelse(bp);
- return (0);
- }
- if ((bp->b_flags & (B_MANAGED | B_DELWRI)) == (B_MANAGED | B_DELWRI)) {
- bqrelse(bp);
- return (0);
- }
-
- node = VTON(bp->b_vp);
- nffsdev = node->nn_nandfsdev;
- DPRINTF(BUF, ("%s: buf:%p\n", __func__, bp));
- ino = node->nn_ino;
-
- if (nandfs_fs_full(nffsdev) && !NANDFS_SYS_NODE(ino) && !force) {
- brelse(bp);
- return (ENOSPC);
- }
-
- bp->b_flags |= B_MANAGED;
- bdwrite(bp);
-
- nandfs_dirty_bufs_increment(nffsdev);
-
- KASSERT((bp->b_vp), ("vp missing for bp"));
- KASSERT((nandfs_vblk_get(bp) || ino == NANDFS_DAT_INO),
- ("bp vblk is 0"));
-
- /*
- * To maintain consistency of FS we need to force making
- * meta buffers dirty, even if free space is low.
- */
- if (dirty_meta && ino != NANDFS_GC_INO)
- nandfs_bmap_dirty_blocks(VTON(bp->b_vp), bp, 1);
-
- bps = nffsdev->nd_fsdata.f_blocks_per_segment;
-
- if (nffsdev->nd_dirty_bufs >= (bps * nandfs_max_dirty_segs)) {
- mtx_lock(&nffsdev->nd_sync_mtx);
- if (nffsdev->nd_syncing == 0) {
- DPRINTF(SYNC, ("%s: wakeup gc\n", __func__));
- nffsdev->nd_syncing = 1;
- wakeup(&nffsdev->nd_syncing);
- }
- mtx_unlock(&nffsdev->nd_sync_mtx);
- }
-
- return (0);
-}
-
-int
-nandfs_dirty_buf(struct buf *bp, int force)
-{
-
- return (_nandfs_dirty_buf(bp, 1, force));
-}
-
-int
-nandfs_dirty_buf_meta(struct buf *bp, int force)
-{
-
- return (_nandfs_dirty_buf(bp, 0, force));
-}
-
-void
-nandfs_undirty_buf_fsdev(struct nandfs_device *nffsdev, struct buf *bp)
-{
-
- BUF_ASSERT_HELD(bp);
-
- if (bp->b_flags & B_DELWRI) {
- bp->b_flags &= ~(B_DELWRI|B_MANAGED);
- nandfs_dirty_bufs_decrement(nffsdev);
- }
- /*
- * Since it is now being written, we can clear its deferred write flag.
- */
- bp->b_flags &= ~B_DEFERRED;
-
- brelse(bp);
-}
-
-void
-nandfs_undirty_buf(struct buf *bp)
-{
- struct nandfs_node *node;
-
- node = VTON(bp->b_vp);
-
- nandfs_undirty_buf_fsdev(node->nn_nandfsdev, bp);
-}
-
-void
-nandfs_vblk_set(struct buf *bp, nandfs_daddr_t blocknr)
-{
-
- nandfs_daddr_t *vblk = (nandfs_daddr_t *)(&bp->b_fsprivate1);
- *vblk = blocknr;
-}
-
-nandfs_daddr_t
-nandfs_vblk_get(struct buf *bp)
-{
-
- nandfs_daddr_t *vblk = (nandfs_daddr_t *)(&bp->b_fsprivate1);
- return (*vblk);
-}
-
-void
-nandfs_buf_set(struct buf *bp, uint32_t bits)
-{
- uintptr_t flags;
-
- flags = (uintptr_t)bp->b_fsprivate3;
- flags |= (uintptr_t)bits;
- bp->b_fsprivate3 = (void *)flags;
-}
-
-void
-nandfs_buf_clear(struct buf *bp, uint32_t bits)
-{
- uintptr_t flags;
-
- flags = (uintptr_t)bp->b_fsprivate3;
- flags &= ~(uintptr_t)bits;
- bp->b_fsprivate3 = (void *)flags;
-}
-
-int
-nandfs_buf_check(struct buf *bp, uint32_t bits)
-{
- uintptr_t flags;
-
- flags = (uintptr_t)bp->b_fsprivate3;
- if (flags & bits)
- return (1);
- return (0);
-}
-
-int
-nandfs_erase(struct nandfs_device *fsdev, off_t offset, size_t size)
-{
- DPRINTF(BLOCK, ("%s: performing erase at offset %jx size %zx\n",
- __func__, offset, size));
-
- MPASS(size % fsdev->nd_erasesize == 0);
-
- return (g_delete_data(fsdev->nd_gconsumer, offset, size));
-}
-
-int
-nandfs_vop_islocked(struct vnode *vp)
-{
- int islocked;
-
- islocked = VOP_ISLOCKED(vp);
- return (islocked == LK_EXCLUSIVE || islocked == LK_SHARED);
-}
-
-nandfs_daddr_t
-nandfs_block_to_dblock(struct nandfs_device *fsdev, nandfs_lbn_t block)
-{
-
- return (btodb(block * fsdev->nd_blocksize));
-}
diff --git a/sys/fs/nandfs/nandfs_subr.h b/sys/fs/nandfs/nandfs_subr.h
deleted file mode 100644
index 36c2c9dc2ff2..000000000000
--- a/sys/fs/nandfs/nandfs_subr.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs_subr.h,v 1.1 2009/07/18 16:31:42 reinoud
- *
- * $FreeBSD$
- */
-
-#ifndef _FS_NANDFS_NANDFS_SUBR_H_
-#define _FS_NANDFS_NANDFS_SUBR_H_
-
-struct nandfs_mdt;
-
-struct nandfs_alloc_request
-{
- uint64_t entrynum;
- struct buf *bp_desc;
- struct buf *bp_bitmap;
- struct buf *bp_entry;
-};
-
-/* Segment creation */
-void nandfs_wakeup_wait_sync(struct nandfs_device *, int);
-int nandfs_segment_constructor(struct nandfsmount *, int);
-int nandfs_sync_file(struct vnode *);
-
-/* Basic calculators */
-uint64_t nandfs_get_segnum_of_block(struct nandfs_device *, nandfs_daddr_t);
-void nandfs_get_segment_range(struct nandfs_device *, uint64_t, uint64_t *,
- uint64_t *);
-void nandfs_calc_mdt_consts(struct nandfs_device *, struct nandfs_mdt *, int);
-
-/* Log reading / volume helpers */
-int nandfs_search_super_root(struct nandfs_device *);
-
-/* Reading */
-int nandfs_dev_bread(struct nandfs_device *, nandfs_daddr_t, struct ucred *,
- int, struct buf **);
-int nandfs_bread(struct nandfs_node *, nandfs_lbn_t, struct ucred *, int,
- struct buf **);
-int nandfs_bread_meta(struct nandfs_node *, nandfs_lbn_t, struct ucred *, int,
- struct buf **);
-int nandfs_bdestroy(struct nandfs_node *, nandfs_daddr_t);
-int nandfs_bcreate(struct nandfs_node *, nandfs_lbn_t, struct ucred *, int,
- struct buf **);
-int nandfs_bcreate_meta(struct nandfs_node *, nandfs_lbn_t, struct ucred *,
- int, struct buf **);
-int nandfs_bread_create(struct nandfs_node *, nandfs_lbn_t, struct ucred *,
- int, struct buf **);
-
-/* vtop operations */
-int nandfs_vtop(struct nandfs_node *, nandfs_daddr_t, nandfs_daddr_t *);
-
-/* Node action implementators */
-int nandfs_vinit(struct vnode *, uint64_t);
-int nandfs_get_node(struct nandfsmount *, uint64_t, struct nandfs_node **);
-int nandfs_get_node_raw(struct nandfs_device *, struct nandfsmount *, uint64_t,
- struct nandfs_inode *, struct nandfs_node **);
-void nandfs_dispose_node(struct nandfs_node **);
-
-void nandfs_itimes(struct vnode *);
-int nandfs_lookup_name_in_dir(struct vnode *, const char *, int, uint64_t *,
- int *, uint64_t *);
-int nandfs_create_node(struct vnode *, struct vnode **, struct vattr *,
- struct componentname *);
-void nandfs_delete_node(struct nandfs_node *);
-
-int nandfs_chsize(struct vnode *, u_quad_t, struct ucred *);
-int nandfs_dir_detach(struct nandfsmount *, struct nandfs_node *,
- struct nandfs_node *, struct componentname *);
-int nandfs_dir_attach(struct nandfsmount *, struct nandfs_node *,
- struct nandfs_node *, struct vattr *, struct componentname *);
-
-int nandfs_dirty_buf(struct buf *, int);
-int nandfs_dirty_buf_meta(struct buf *, int);
-int nandfs_fs_full(struct nandfs_device *);
-void nandfs_undirty_buf_fsdev(struct nandfs_device *, struct buf *);
-void nandfs_undirty_buf(struct buf *);
-
-void nandfs_clear_buf(struct buf *);
-void nandfs_buf_set(struct buf *, uint32_t);
-void nandfs_buf_clear(struct buf *, uint32_t);
-int nandfs_buf_check(struct buf *, uint32_t);
-
-int nandfs_find_free_entry(struct nandfs_mdt *, struct nandfs_node *,
- struct nandfs_alloc_request *);
-int nandfs_find_entry(struct nandfs_mdt *, struct nandfs_node *,
- struct nandfs_alloc_request *);
-int nandfs_alloc_entry(struct nandfs_mdt *, struct nandfs_alloc_request *);
-void nandfs_abort_entry(struct nandfs_alloc_request *);
-int nandfs_free_entry(struct nandfs_mdt *, struct nandfs_alloc_request *);
-int nandfs_get_entry_block(struct nandfs_mdt *, struct nandfs_node *,
- struct nandfs_alloc_request *, uint32_t *, int);
-
-/* Inode management. */
-int nandfs_node_create(struct nandfsmount *, struct nandfs_node **, uint16_t);
-int nandfs_node_destroy(struct nandfs_node *);
-int nandfs_node_update(struct nandfs_node *);
-int nandfs_get_node_entry(struct nandfsmount *, struct nandfs_inode **,
- uint64_t, struct buf **);
-void nandfs_mdt_trans_blk(struct nandfs_mdt *, uint64_t, uint64_t *,
- uint64_t *, nandfs_lbn_t *, uint32_t *);
-
-/* vblock management */
-void nandfs_mdt_trans(struct nandfs_mdt *, uint64_t, nandfs_lbn_t *, uint32_t *);
-int nandfs_vblock_alloc(struct nandfs_device *, nandfs_daddr_t *);
-int nandfs_vblock_end(struct nandfs_device *, nandfs_daddr_t);
-int nandfs_vblock_assign(struct nandfs_device *, nandfs_daddr_t,
- nandfs_lbn_t);
-int nandfs_vblock_free(struct nandfs_device *, nandfs_daddr_t);
-
-/* Checkpoint management */
-int nandfs_get_checkpoint(struct nandfs_device *, struct nandfs_node *,
- uint64_t);
-int nandfs_set_checkpoint(struct nandfs_device *, struct nandfs_node *,
- uint64_t, struct nandfs_inode *, uint64_t);
-
-/* Segment management */
-int nandfs_alloc_segment(struct nandfs_device *, uint64_t *);
-int nandfs_update_segment(struct nandfs_device *, uint64_t, uint32_t);
-int nandfs_free_segment(struct nandfs_device *, uint64_t);
-int nandfs_clear_segment(struct nandfs_device *, uint64_t);
-int nandfs_touch_segment(struct nandfs_device *, uint64_t);
-int nandfs_markgc_segment(struct nandfs_device *, uint64_t);
-
-int nandfs_bmap_insert_block(struct nandfs_node *, nandfs_lbn_t, struct buf *);
-int nandfs_bmap_update_block(struct nandfs_node *, struct buf *, nandfs_lbn_t);
-int nandfs_bmap_update_dat(struct nandfs_node *, nandfs_daddr_t, struct buf *);
-int nandfs_bmap_dirty_blocks(struct nandfs_node *, struct buf *, int);
-int nandfs_bmap_truncate_mapping(struct nandfs_node *, nandfs_lbn_t,
- nandfs_lbn_t);
-int nandfs_bmap_lookup(struct nandfs_node *, nandfs_lbn_t, nandfs_daddr_t *);
-
-/* dirent */
-int nandfs_add_dirent(struct vnode *, uint64_t, char *, long, uint8_t);
-int nandfs_remove_dirent(struct vnode *, struct nandfs_node *,
- struct componentname *);
-int nandfs_update_dirent(struct vnode *, struct nandfs_node *,
- struct nandfs_node *);
-int nandfs_init_dir(struct vnode *, uint64_t, uint64_t);
-int nandfs_update_parent_dir(struct vnode *, uint64_t);
-
-void nandfs_vblk_set(struct buf *, nandfs_daddr_t);
-nandfs_daddr_t nandfs_vblk_get(struct buf *);
-
-void nandfs_inode_init(struct nandfs_inode *, uint16_t);
-void nandfs_inode_destroy(struct nandfs_inode *);
-
-/* ioctl */
-int nandfs_get_seg_stat(struct nandfs_device *, struct nandfs_seg_stat *);
-int nandfs_chng_cpmode(struct nandfs_node *, struct nandfs_cpmode *);
-int nandfs_get_cpinfo_ioctl(struct nandfs_node *, struct nandfs_argv *);
-int nandfs_delete_cp(struct nandfs_node *, uint64_t start, uint64_t);
-int nandfs_make_snap(struct nandfs_device *, uint64_t *);
-int nandfs_delete_snap(struct nandfs_device *, uint64_t);
-int nandfs_get_cpstat(struct nandfs_node *, struct nandfs_cpstat *);
-int nandfs_get_segment_info_ioctl(struct nandfs_device *, struct nandfs_argv *);
-int nandfs_get_dat_vinfo_ioctl(struct nandfs_device *, struct nandfs_argv *);
-int nandfs_get_dat_bdescs_ioctl(struct nandfs_device *, struct nandfs_argv *);
-int nandfs_get_fsinfo(struct nandfsmount *, struct nandfs_fsinfo *);
-
-int nandfs_get_cpinfo(struct nandfs_node *, uint64_t, uint16_t,
- struct nandfs_cpinfo *, uint32_t, uint32_t *);
-
-nandfs_lbn_t nandfs_get_maxfilesize(struct nandfs_device *);
-
-int nandfs_write_superblock(struct nandfs_device *);
-
-extern int nandfs_sync_interval;
-extern int nandfs_max_dirty_segs;
-extern int nandfs_cps_between_sblocks;
-
-struct buf *nandfs_geteblk(int, int);
-
-void nandfs_dirty_bufs_increment(struct nandfs_device *);
-void nandfs_dirty_bufs_decrement(struct nandfs_device *);
-
-int nandfs_start_cleaner(struct nandfs_device *);
-int nandfs_stop_cleaner(struct nandfs_device *);
-
-int nandfs_segsum_valid(struct nandfs_segment_summary *);
-int nandfs_load_segsum(struct nandfs_device *, nandfs_daddr_t,
- struct nandfs_segment_summary *);
-int nandfs_get_segment_info(struct nandfs_device *, struct nandfs_suinfo *,
- uint32_t, uint64_t);
-int nandfs_get_segment_info_filter(struct nandfs_device *,
- struct nandfs_suinfo *, uint32_t, uint64_t, uint64_t *, uint32_t, uint32_t);
-int nandfs_get_dat_vinfo(struct nandfs_device *, struct nandfs_vinfo *,
- uint32_t);
-int nandfs_get_dat_bdescs(struct nandfs_device *, struct nandfs_bdesc *,
- uint32_t);
-
-#define NANDFS_VBLK_ASSIGNED 1
-
-#define NANDFS_IS_INDIRECT(bp) ((bp)->b_lblkno < 0)
-
-int nandfs_erase(struct nandfs_device *, off_t, size_t);
-
-#define NANDFS_VOP_ISLOCKED(vp) nandfs_vop_islocked((vp))
-int nandfs_vop_islocked(struct vnode *vp);
-
-nandfs_daddr_t nandfs_block_to_dblock(struct nandfs_device *, nandfs_lbn_t);
-
-#define DEBUG_MODE
-#if defined(DEBUG_MODE)
-#define nandfs_error panic
-#define nandfs_warning printf
-#elif defined(TEST_MODE)
-#define nandfs_error printf
-#define nandfs_warning printf
-#else
-#define nandfs_error(...)
-#define nandfs_warning(...)
-#endif
-
-#endif /* !_FS_NANDFS_NANDFS_SUBR_H_ */
diff --git a/sys/fs/nandfs/nandfs_sufile.c b/sys/fs/nandfs/nandfs_sufile.c
deleted file mode 100644
index 5276008de096..000000000000
--- a/sys/fs/nandfs/nandfs_sufile.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-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/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/sysctl.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-#define SU_USAGE_OFF(bp, offset) \
- ((struct nandfs_segment_usage *)((bp)->b_data + offset))
-
-static int
-nandfs_seg_usage_blk_offset(struct nandfs_device *fsdev, uint64_t seg,
- uint64_t *blk, uint64_t *offset)
-{
- uint64_t off;
- uint16_t seg_size;
-
- seg_size = fsdev->nd_fsdata.f_segment_usage_size;
-
- off = roundup(sizeof(struct nandfs_sufile_header), seg_size);
- off += (seg * seg_size);
-
- *blk = off / fsdev->nd_blocksize;
- *offset = off % fsdev->nd_blocksize;
- return (0);
-}
-
-/* Alloc new segment */
-int
-nandfs_alloc_segment(struct nandfs_device *fsdev, uint64_t *seg)
-{
- struct nandfs_node *su_node;
- struct nandfs_sufile_header *su_header;
- struct nandfs_segment_usage *su_usage;
- struct buf *bp_header, *bp;
- uint64_t blk, vblk, offset, i, rest, nsegments;
- uint16_t seg_size;
- int error, found;
-
- seg_size = fsdev->nd_fsdata.f_segment_usage_size;
- nsegments = fsdev->nd_fsdata.f_nsegments;
-
- su_node = fsdev->nd_su_node;
- ASSERT_VOP_LOCKED(NTOV(su_node), __func__);
-
- /* Read header buffer */
- error = nandfs_bread(su_node, 0, NOCRED, 0, &bp_header);
- if (error) {
- brelse(bp_header);
- return (error);
- }
-
- su_header = (struct nandfs_sufile_header *)bp_header->b_data;
-
- /* Get last allocated segment */
- i = su_header->sh_last_alloc + 1;
-
- found = 0;
- bp = NULL;
- while (!found) {
- nandfs_seg_usage_blk_offset(fsdev, i, &blk, &offset);
- if(blk != 0) {
- error = nandfs_bmap_lookup(su_node, blk, &vblk);
- if (error) {
- nandfs_error("%s: cannot find vblk for blk "
- "blk:%jx\n", __func__, blk);
- return (error);
- }
- if (vblk)
- error = nandfs_bread(su_node, blk, NOCRED, 0,
- &bp);
- else
- error = nandfs_bcreate(su_node, blk, NOCRED, 0,
- &bp);
- if (error) {
- nandfs_error("%s: cannot create/read "
- "vblk:%jx\n", __func__, vblk);
- if (bp)
- brelse(bp);
- return (error);
- }
-
- su_usage = SU_USAGE_OFF(bp, offset);
- } else {
- su_usage = SU_USAGE_OFF(bp_header, offset);
- bp = bp_header;
- }
-
- rest = (fsdev->nd_blocksize - offset) / seg_size;
- /* Go through all su usage in block */
- while (rest) {
- /* When last check start from beginning */
- if (i == nsegments)
- break;
-
- if (!su_usage->su_flags) {
- su_usage->su_flags = 1;
- found = 1;
- break;
- }
- su_usage++;
- i++;
-
- /* If all checked return error */
- if (i == su_header->sh_last_alloc) {
- DPRINTF(SEG, ("%s: cannot allocate segment \n",
- __func__));
- brelse(bp_header);
- if (blk != 0)
- brelse(bp);
- return (1);
- }
- rest--;
- }
- if (!found) {
- /* Otherwise read another block */
- if (blk != 0)
- brelse(bp);
- if (i == nsegments) {
- blk = 0;
- i = 0;
- } else
- blk++;
- offset = 0;
- }
- }
-
- if (found) {
- *seg = i;
- su_header->sh_last_alloc = i;
- su_header->sh_ncleansegs--;
- su_header->sh_ndirtysegs++;
-
- fsdev->nd_super.s_free_blocks_count = su_header->sh_ncleansegs *
- fsdev->nd_fsdata.f_blocks_per_segment;
- fsdev->nd_clean_segs--;
-
- /*
- * It is mostly called from syncer() so we want to force
- * making buf dirty.
- */
- error = nandfs_dirty_buf(bp_header, 1);
- if (error) {
- if (bp && bp != bp_header)
- brelse(bp);
- return (error);
- }
- if (bp && bp != bp_header)
- nandfs_dirty_buf(bp, 1);
-
- DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)i));
-
- return (0);
- }
-
- DPRINTF(SEG, ("%s: failed\n", __func__));
-
- return (1);
-}
-
-/*
- * Make buffer dirty, it will be updated soon but first it need to be
- * gathered by syncer.
- */
-int
-nandfs_touch_segment(struct nandfs_device *fsdev, uint64_t seg)
-{
- struct nandfs_node *su_node;
- struct buf *bp;
- uint64_t blk, offset;
- int error;
-
- su_node = fsdev->nd_su_node;
- ASSERT_VOP_LOCKED(NTOV(su_node), __func__);
-
- nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset);
-
- error = nandfs_bread(su_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- nandfs_error("%s: cannot preallocate new segment\n", __func__);
- return (error);
- } else
- nandfs_dirty_buf(bp, 1);
-
- DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg));
- return (error);
-}
-
-/* Update block count of segment */
-int
-nandfs_update_segment(struct nandfs_device *fsdev, uint64_t seg, uint32_t nblks)
-{
- struct nandfs_node *su_node;
- struct nandfs_segment_usage *su_usage;
- struct buf *bp;
- uint64_t blk, offset;
- int error;
-
- su_node = fsdev->nd_su_node;
- ASSERT_VOP_LOCKED(NTOV(su_node), __func__);
-
- nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset);
-
- error = nandfs_bread(su_node, blk, NOCRED, 0, &bp);
- if (error) {
- nandfs_error("%s: read block:%jx to update\n",
- __func__, blk);
- brelse(bp);
- return (error);
- }
-
- su_usage = SU_USAGE_OFF(bp, offset);
- su_usage->su_lastmod = fsdev->nd_ts.tv_sec;
- su_usage->su_flags = NANDFS_SEGMENT_USAGE_DIRTY;
- su_usage->su_nblocks += nblks;
-
- DPRINTF(SEG, ("%s: seg:%#jx inc:%#x cur:%#x\n", __func__,
- (uintmax_t)seg, nblks, su_usage->su_nblocks));
-
- nandfs_dirty_buf(bp, 1);
-
- return (0);
-}
-
-/* Make segment free */
-int
-nandfs_free_segment(struct nandfs_device *fsdev, uint64_t seg)
-{
- struct nandfs_node *su_node;
- struct nandfs_sufile_header *su_header;
- struct nandfs_segment_usage *su_usage;
- struct buf *bp_header, *bp;
- uint64_t blk, offset;
- int error;
-
- su_node = fsdev->nd_su_node;
- ASSERT_VOP_LOCKED(NTOV(su_node), __func__);
-
- /* Read su header */
- error = nandfs_bread(su_node, 0, NOCRED, 0, &bp_header);
- if (error) {
- brelse(bp_header);
- return (error);
- }
-
- su_header = (struct nandfs_sufile_header *)bp_header->b_data;
- nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset);
-
- /* Read su usage block if other than su header block */
- if (blk != 0) {
- error = nandfs_bread(su_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- brelse(bp_header);
- return (error);
- }
- } else
- bp = bp_header;
-
- /* Reset su usage data */
- su_usage = SU_USAGE_OFF(bp, offset);
- su_usage->su_lastmod = fsdev->nd_ts.tv_sec;
- su_usage->su_nblocks = 0;
- su_usage->su_flags = 0;
-
- /* Update clean/dirty counter in header */
- su_header->sh_ncleansegs++;
- su_header->sh_ndirtysegs--;
-
- /*
- * Make buffers dirty, called by cleaner
- * so force dirty even if no much space left
- * on device
- */
- nandfs_dirty_buf(bp_header, 1);
- if (bp != bp_header)
- nandfs_dirty_buf(bp, 1);
-
- /* Update free block count */
- fsdev->nd_super.s_free_blocks_count = su_header->sh_ncleansegs *
- fsdev->nd_fsdata.f_blocks_per_segment;
- fsdev->nd_clean_segs++;
-
- DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg));
-
- return (0);
-}
-
-static int
-nandfs_bad_segment(struct nandfs_device *fsdev, uint64_t seg)
-{
- struct nandfs_node *su_node;
- struct nandfs_segment_usage *su_usage;
- struct buf *bp;
- uint64_t blk, offset;
- int error;
-
- su_node = fsdev->nd_su_node;
- ASSERT_VOP_LOCKED(NTOV(su_node), __func__);
-
- nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset);
-
- error = nandfs_bread(su_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- su_usage = SU_USAGE_OFF(bp, offset);
- su_usage->su_lastmod = fsdev->nd_ts.tv_sec;
- su_usage->su_flags = NANDFS_SEGMENT_USAGE_ERROR;
-
- DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg));
-
- nandfs_dirty_buf(bp, 1);
-
- return (0);
-}
-
-int
-nandfs_markgc_segment(struct nandfs_device *fsdev, uint64_t seg)
-{
- struct nandfs_node *su_node;
- struct nandfs_segment_usage *su_usage;
- struct buf *bp;
- uint64_t blk, offset;
- int error;
-
- su_node = fsdev->nd_su_node;
-
- VOP_LOCK(NTOV(su_node), LK_EXCLUSIVE);
-
- nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset);
-
- error = nandfs_bread(su_node, blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- VOP_UNLOCK(NTOV(su_node), 0);
- return (error);
- }
-
- su_usage = SU_USAGE_OFF(bp, offset);
- MPASS((su_usage->su_flags & NANDFS_SEGMENT_USAGE_GC) == 0);
- su_usage->su_flags |= NANDFS_SEGMENT_USAGE_GC;
-
- brelse(bp);
- VOP_UNLOCK(NTOV(su_node), 0);
-
- DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg));
-
- return (0);
-}
-
-int
-nandfs_clear_segment(struct nandfs_device *fsdev, uint64_t seg)
-{
- uint64_t offset, segsize;
- uint32_t bps, bsize;
- int error = 0;
-
- bps = fsdev->nd_fsdata.f_blocks_per_segment;
- bsize = fsdev->nd_blocksize;
- segsize = bsize * bps;
- nandfs_get_segment_range(fsdev, seg, &offset, NULL);
- offset *= bsize;
-
- DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg));
-
- /* Erase it and mark it bad when fail */
- if (nandfs_erase(fsdev, offset, segsize))
- error = nandfs_bad_segment(fsdev, seg);
-
- if (error)
- return (error);
-
- /* Mark it free */
- error = nandfs_free_segment(fsdev, seg);
-
- return (error);
-}
-
-int
-nandfs_get_seg_stat(struct nandfs_device *nandfsdev,
- struct nandfs_seg_stat *nss)
-{
- struct nandfs_sufile_header *suhdr;
- struct nandfs_node *su_node;
- struct buf *bp;
- int err;
-
- su_node = nandfsdev->nd_su_node;
-
- NANDFS_WRITELOCK(nandfsdev);
- VOP_LOCK(NTOV(su_node), LK_SHARED);
- err = nandfs_bread(nandfsdev->nd_su_node, 0, NOCRED, 0, &bp);
- if (err) {
- brelse(bp);
- VOP_UNLOCK(NTOV(su_node), 0);
- NANDFS_WRITEUNLOCK(nandfsdev);
- return (-1);
- }
-
- suhdr = (struct nandfs_sufile_header *)bp->b_data;
- nss->nss_nsegs = nandfsdev->nd_fsdata.f_nsegments;
- nss->nss_ncleansegs = suhdr->sh_ncleansegs;
- nss->nss_ndirtysegs = suhdr->sh_ndirtysegs;
- nss->nss_ctime = 0;
- nss->nss_nongc_ctime = nandfsdev->nd_ts.tv_sec;
- nss->nss_prot_seq = nandfsdev->nd_seg_sequence;
-
- brelse(bp);
- VOP_UNLOCK(NTOV(su_node), 0);
-
- NANDFS_WRITEUNLOCK(nandfsdev);
-
- return (0);
-}
-
-int
-nandfs_get_segment_info_ioctl(struct nandfs_device *fsdev,
- struct nandfs_argv *nargv)
-{
- struct nandfs_suinfo *nsi;
- int error;
-
- if (nargv->nv_nmembs > NANDFS_SEGMENTS_MAX)
- return (EINVAL);
-
- nsi = malloc(sizeof(struct nandfs_suinfo) * nargv->nv_nmembs,
- M_NANDFSTEMP, M_WAITOK | M_ZERO);
-
- error = nandfs_get_segment_info(fsdev, nsi, nargv->nv_nmembs,
- nargv->nv_index);
-
- if (error == 0)
- error = copyout(nsi, (void *)(uintptr_t)nargv->nv_base,
- sizeof(struct nandfs_suinfo) * nargv->nv_nmembs);
-
- free(nsi, M_NANDFSTEMP);
- return (error);
-}
-
-int
-nandfs_get_segment_info(struct nandfs_device *fsdev, struct nandfs_suinfo *nsi,
- uint32_t nmembs, uint64_t segment)
-{
-
- return (nandfs_get_segment_info_filter(fsdev, nsi, nmembs, segment,
- NULL, 0, 0));
-}
-
-int
-nandfs_get_segment_info_filter(struct nandfs_device *fsdev,
- struct nandfs_suinfo *nsi, uint32_t nmembs, uint64_t segment,
- uint64_t *nsegs, uint32_t filter, uint32_t nfilter)
-{
- struct nandfs_segment_usage *su;
- struct nandfs_node *su_node;
- struct buf *bp;
- uint64_t curr, blocknr, blockoff, i;
- uint32_t flags;
- int err = 0;
-
- curr = ~(0);
-
- lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL);
- su_node = fsdev->nd_su_node;
-
- VOP_LOCK(NTOV(su_node), LK_SHARED);
-
- bp = NULL;
- if (nsegs != NULL)
- *nsegs = 0;
- for (i = 0; i < nmembs; segment++) {
- if (segment == fsdev->nd_fsdata.f_nsegments)
- break;
-
- nandfs_seg_usage_blk_offset(fsdev, segment, &blocknr,
- &blockoff);
-
- if (i == 0 || curr != blocknr) {
- if (bp != NULL)
- brelse(bp);
- err = nandfs_bread(su_node, blocknr, NOCRED,
- 0, &bp);
- if (err) {
- goto out;
- }
- curr = blocknr;
- }
-
- su = SU_USAGE_OFF(bp, blockoff);
- flags = su->su_flags;
- if (segment == fsdev->nd_seg_num ||
- segment == fsdev->nd_next_seg_num)
- flags |= NANDFS_SEGMENT_USAGE_ACTIVE;
-
- if (nfilter != 0 && (flags & nfilter) != 0)
- continue;
- if (filter != 0 && (flags & filter) == 0)
- continue;
-
- nsi->nsi_num = segment;
- nsi->nsi_lastmod = su->su_lastmod;
- nsi->nsi_blocks = su->su_nblocks;
- nsi->nsi_flags = flags;
- nsi++;
- i++;
- if (nsegs != NULL)
- (*nsegs)++;
- }
-
-out:
- if (bp != NULL)
- brelse(bp);
- VOP_UNLOCK(NTOV(su_node), 0);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
-
- return (err);
-}
diff --git a/sys/fs/nandfs/nandfs_vfsops.c b/sys/fs/nandfs/nandfs_vfsops.c
deleted file mode 100644
index f703044728ef..000000000000
--- a/sys/fs/nandfs/nandfs_vfsops.c
+++ /dev/null
@@ -1,1601 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs_vfsops.c,v 1.1 2009/07/18 16:31:42 reinoud Exp
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/fcntl.h>
-#include <sys/gsb_crc32.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/proc.h>
-#include <sys/priv.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/sysctl.h>
-#include <sys/libkern.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-#include <machine/_inttypes.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-static MALLOC_DEFINE(M_NANDFSMNT, "nandfs_mount", "NANDFS mount structure");
-
-#define NANDFS_SET_SYSTEMFILE(vp) { \
- (vp)->v_vflag |= VV_SYSTEM; \
- vref(vp); \
- vput(vp); }
-
-#define NANDFS_UNSET_SYSTEMFILE(vp) { \
- VOP_LOCK(vp, LK_EXCLUSIVE); \
- MPASS(vp->v_bufobj.bo_dirty.bv_cnt == 0); \
- (vp)->v_vflag &= ~VV_SYSTEM; \
- vgone(vp); \
- vput(vp); }
-
-/* Globals */
-struct _nandfs_devices nandfs_devices;
-
-/* Parameters */
-int nandfs_verbose = 0;
-
-static void
-nandfs_tunable_init(void *arg)
-{
-
- TUNABLE_INT_FETCH("vfs.nandfs.verbose", &nandfs_verbose);
-}
-SYSINIT(nandfs_tunables, SI_SUB_VFS, SI_ORDER_ANY, nandfs_tunable_init, NULL);
-
-static SYSCTL_NODE(_vfs, OID_AUTO, nandfs, CTLFLAG_RD, 0, "NAND filesystem");
-static SYSCTL_NODE(_vfs_nandfs, OID_AUTO, mount, CTLFLAG_RD, 0,
- "NANDFS mountpoints");
-SYSCTL_INT(_vfs_nandfs, OID_AUTO, verbose, CTLFLAG_RW, &nandfs_verbose, 0, "");
-
-#define NANDFS_CONSTR_INTERVAL 5
-int nandfs_sync_interval = NANDFS_CONSTR_INTERVAL; /* sync every 5 seconds */
-SYSCTL_UINT(_vfs_nandfs, OID_AUTO, sync_interval, CTLFLAG_RW,
- &nandfs_sync_interval, 0, "");
-
-#define NANDFS_MAX_DIRTY_SEGS 5
-int nandfs_max_dirty_segs = NANDFS_MAX_DIRTY_SEGS; /* sync when 5 dirty seg */
-SYSCTL_UINT(_vfs_nandfs, OID_AUTO, max_dirty_segs, CTLFLAG_RW,
- &nandfs_max_dirty_segs, 0, "");
-
-#define NANDFS_CPS_BETWEEN_SBLOCKS 5
-int nandfs_cps_between_sblocks = NANDFS_CPS_BETWEEN_SBLOCKS; /* write superblock every 5 checkpoints */
-SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cps_between_sblocks, CTLFLAG_RW,
- &nandfs_cps_between_sblocks, 0, "");
-
-#define NANDFS_CLEANER_ENABLE 1
-int nandfs_cleaner_enable = NANDFS_CLEANER_ENABLE;
-SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cleaner_enable, CTLFLAG_RW,
- &nandfs_cleaner_enable, 0, "");
-
-#define NANDFS_CLEANER_INTERVAL 5
-int nandfs_cleaner_interval = NANDFS_CLEANER_INTERVAL;
-SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cleaner_interval, CTLFLAG_RW,
- &nandfs_cleaner_interval, 0, "");
-
-#define NANDFS_CLEANER_SEGMENTS 5
-int nandfs_cleaner_segments = NANDFS_CLEANER_SEGMENTS;
-SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cleaner_segments, CTLFLAG_RW,
- &nandfs_cleaner_segments, 0, "");
-
-static int nandfs_mountfs(struct vnode *devvp, struct mount *mp);
-static vfs_mount_t nandfs_mount;
-static vfs_root_t nandfs_root;
-static vfs_statfs_t nandfs_statfs;
-static vfs_unmount_t nandfs_unmount;
-static vfs_vget_t nandfs_vget;
-static vfs_sync_t nandfs_sync;
-static const char *nandfs_opts[] = {
- "snap", "from", "noatime", NULL
-};
-
-/* System nodes */
-static int
-nandfs_create_system_nodes(struct nandfs_device *nandfsdev)
-{
- int error;
-
- error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_DAT_INO,
- &nandfsdev->nd_super_root.sr_dat, &nandfsdev->nd_dat_node);
- if (error)
- goto errorout;
-
- error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_CPFILE_INO,
- &nandfsdev->nd_super_root.sr_cpfile, &nandfsdev->nd_cp_node);
- if (error)
- goto errorout;
-
- error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_SUFILE_INO,
- &nandfsdev->nd_super_root.sr_sufile, &nandfsdev->nd_su_node);
- if (error)
- goto errorout;
-
- error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_GC_INO,
- NULL, &nandfsdev->nd_gc_node);
- if (error)
- goto errorout;
-
- NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_dat_node));
- NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_cp_node));
- NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_su_node));
- NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_gc_node));
-
- DPRINTF(VOLUMES, ("System vnodes: dat: %p cp: %p su: %p\n",
- NTOV(nandfsdev->nd_dat_node), NTOV(nandfsdev->nd_cp_node),
- NTOV(nandfsdev->nd_su_node)));
- return (0);
-
-errorout:
- nandfs_dispose_node(&nandfsdev->nd_gc_node);
- nandfs_dispose_node(&nandfsdev->nd_dat_node);
- nandfs_dispose_node(&nandfsdev->nd_cp_node);
- nandfs_dispose_node(&nandfsdev->nd_su_node);
-
- return (error);
-}
-
-static void
-nandfs_release_system_nodes(struct nandfs_device *nandfsdev)
-{
-
- if (!nandfsdev)
- return;
- if (nandfsdev->nd_refcnt > 0)
- return;
-
- if (nandfsdev->nd_gc_node)
- NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_gc_node));
- if (nandfsdev->nd_dat_node)
- NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_dat_node));
- if (nandfsdev->nd_cp_node)
- NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_cp_node));
- if (nandfsdev->nd_su_node)
- NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_su_node));
-}
-
-static int
-nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata)
-{
- uint32_t fsdata_crc, comp_crc;
-
- if (fsdata->f_magic != NANDFS_FSDATA_MAGIC)
- return (0);
-
- /* Preserve CRC */
- fsdata_crc = fsdata->f_sum;
-
- /* Calculate */
- fsdata->f_sum = (0);
- comp_crc = crc32((uint8_t *)fsdata, fsdata->f_bytes);
-
- /* Restore */
- fsdata->f_sum = fsdata_crc;
-
- /* Check CRC */
- return (fsdata_crc == comp_crc);
-}
-
-static int
-nandfs_check_superblock_crc(struct nandfs_fsdata *fsdata,
- struct nandfs_super_block *super)
-{
- uint32_t super_crc, comp_crc;
-
- /* Check super block magic */
- if (super->s_magic != NANDFS_SUPER_MAGIC)
- return (0);
-
- /* Preserve CRC */
- super_crc = super->s_sum;
-
- /* Calculate */
- super->s_sum = (0);
- comp_crc = crc32((uint8_t *)super, fsdata->f_sbbytes);
-
- /* Restore */
- super->s_sum = super_crc;
-
- /* Check CRC */
- return (super_crc == comp_crc);
-}
-
-static void
-nandfs_calc_superblock_crc(struct nandfs_fsdata *fsdata,
- struct nandfs_super_block *super)
-{
- uint32_t comp_crc;
-
- /* Calculate */
- super->s_sum = 0;
- comp_crc = crc32((uint8_t *)super, fsdata->f_sbbytes);
-
- /* Restore */
- super->s_sum = comp_crc;
-}
-
-static int
-nandfs_is_empty(u_char *area, int size)
-{
- int i;
-
- for (i = 0; i < size; i++)
- if (area[i] != 0xff)
- return (0);
-
- return (1);
-}
-
-static __inline int
-nandfs_sblocks_in_esize(struct nandfs_device *fsdev)
-{
-
- return ((fsdev->nd_erasesize - NANDFS_SBLOCK_OFFSET_BYTES) /
- sizeof(struct nandfs_super_block));
-}
-
-static __inline int
-nandfs_max_sblocks(struct nandfs_device *fsdev)
-{
-
- return (NANDFS_NFSAREAS * nandfs_sblocks_in_esize(fsdev));
-}
-
-static __inline int
-nandfs_sblocks_in_block(struct nandfs_device *fsdev)
-{
-
- return (fsdev->nd_devblocksize / sizeof(struct nandfs_super_block));
-}
-
-#if 0
-static __inline int
-nandfs_sblocks_in_first_block(struct nandfs_device *fsdev)
-{
- int n;
-
- n = nandfs_sblocks_in_block(fsdev) -
- NANDFS_SBLOCK_OFFSET_BYTES / sizeof(struct nandfs_super_block);
- if (n < 0)
- n = 0;
-
- return (n);
-}
-#endif
-
-static int
-nandfs_write_superblock_at(struct nandfs_device *fsdev,
- struct nandfs_fsarea *fstp)
-{
- struct nandfs_super_block *super, *supert;
- struct buf *bp;
- int sb_per_sector, sbs_in_fsd, read_block;
- int index, pos, error;
- off_t offset;
-
- DPRINTF(SYNC, ("%s: last_used %d nandfs_sblocks_in_esize %d\n",
- __func__, fstp->last_used, nandfs_sblocks_in_esize(fsdev)));
- if (fstp->last_used == nandfs_sblocks_in_esize(fsdev) - 1)
- index = 0;
- else
- index = fstp->last_used + 1;
-
- super = &fsdev->nd_super;
- supert = NULL;
-
- sb_per_sector = nandfs_sblocks_in_block(fsdev);
- sbs_in_fsd = sizeof(struct nandfs_fsdata) /
- sizeof(struct nandfs_super_block);
- index += sbs_in_fsd;
- offset = fstp->offset;
-
- DPRINTF(SYNC, ("%s: offset %#jx s_last_pseg %#jx s_last_cno %#jx "
- "s_last_seq %#jx wtime %jd index %d\n", __func__, offset,
- super->s_last_pseg, super->s_last_cno, super->s_last_seq,
- super->s_wtime, index));
-
- read_block = btodb(offset + rounddown(index, sb_per_sector) *
- sizeof(struct nandfs_super_block));
-
- DPRINTF(SYNC, ("%s: read_block %#x\n", __func__, read_block));
-
- if (index == sbs_in_fsd) {
- error = nandfs_erase(fsdev, offset, fsdev->nd_erasesize);
- if (error)
- return (error);
-
- error = bread(fsdev->nd_devvp, btodb(offset),
- fsdev->nd_devblocksize, NOCRED, &bp);
- if (error) {
- printf("NANDFS: couldn't read initial data: %d\n",
- error);
- brelse(bp);
- return (error);
- }
- memcpy(bp->b_data, &fsdev->nd_fsdata, sizeof(fsdev->nd_fsdata));
- /*
- * 0xff-out the rest. This bp could be cached, so potentially
- * b_data contains stale super blocks.
- *
- * We don't mind cached bp since most of the time we just add
- * super blocks to already 0xff-out b_data and don't need to
- * perform actual read.
- */
- if (fsdev->nd_devblocksize > sizeof(fsdev->nd_fsdata))
- memset(bp->b_data + sizeof(fsdev->nd_fsdata), 0xff,
- fsdev->nd_devblocksize - sizeof(fsdev->nd_fsdata));
- error = bwrite(bp);
- if (error) {
- printf("NANDFS: cannot rewrite initial data at %jx\n",
- offset);
- return (error);
- }
- }
-
- error = bread(fsdev->nd_devvp, read_block, fsdev->nd_devblocksize,
- NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- supert = (struct nandfs_super_block *)(bp->b_data);
- pos = index % sb_per_sector;
-
- DPRINTF(SYNC, ("%s: storing at %d\n", __func__, pos));
- memcpy(&supert[pos], super, sizeof(struct nandfs_super_block));
-
- /*
- * See comment above in code that performs erase.
- */
- if (pos == 0)
- memset(&supert[1], 0xff,
- (sb_per_sector - 1) * sizeof(struct nandfs_super_block));
-
- error = bwrite(bp);
- if (error) {
- printf("NANDFS: cannot update superblock at %jx\n", offset);
- return (error);
- }
-
- DPRINTF(SYNC, ("%s: fstp->last_used %d -> %d\n", __func__,
- fstp->last_used, index - sbs_in_fsd));
- fstp->last_used = index - sbs_in_fsd;
-
- return (0);
-}
-
-int
-nandfs_write_superblock(struct nandfs_device *fsdev)
-{
- struct nandfs_super_block *super;
- struct timespec ts;
- int error;
- int i, j;
-
- vfs_timestamp(&ts);
-
- super = &fsdev->nd_super;
-
- super->s_last_pseg = fsdev->nd_last_pseg;
- super->s_last_cno = fsdev->nd_last_cno;
- super->s_last_seq = fsdev->nd_seg_sequence;
- super->s_wtime = ts.tv_sec;
-
- nandfs_calc_superblock_crc(&fsdev->nd_fsdata, super);
-
- error = 0;
- for (i = 0, j = fsdev->nd_last_fsarea; i < NANDFS_NFSAREAS;
- i++, j = (j + 1 % NANDFS_NFSAREAS)) {
- if (fsdev->nd_fsarea[j].flags & NANDFS_FSSTOR_FAILED) {
- DPRINTF(SYNC, ("%s: skipping %d\n", __func__, j));
- continue;
- }
- error = nandfs_write_superblock_at(fsdev, &fsdev->nd_fsarea[j]);
- if (error) {
- printf("NANDFS: writing superblock at offset %d failed:"
- "%d\n", j * fsdev->nd_erasesize, error);
- fsdev->nd_fsarea[j].flags |= NANDFS_FSSTOR_FAILED;
- } else
- break;
- }
-
- if (i == NANDFS_NFSAREAS) {
- printf("NANDFS: superblock was not written\n");
- /*
- * TODO: switch to read-only?
- */
- return (error);
- } else
- fsdev->nd_last_fsarea = (j + 1) % NANDFS_NFSAREAS;
-
- return (0);
-}
-
-static int
-nandfs_select_fsdata(struct nandfs_device *fsdev,
- struct nandfs_fsdata *fsdatat, struct nandfs_fsdata **fsdata, int nfsds)
-{
- int i;
-
- *fsdata = NULL;
- for (i = 0; i < nfsds; i++) {
- DPRINTF(VOLUMES, ("%s: i %d f_magic %x f_crc %x\n", __func__,
- i, fsdatat[i].f_magic, fsdatat[i].f_sum));
- if (!nandfs_check_fsdata_crc(&fsdatat[i]))
- continue;
- *fsdata = &fsdatat[i];
- break;
- }
-
- return (*fsdata != NULL ? 0 : EINVAL);
-}
-
-static int
-nandfs_select_sb(struct nandfs_device *fsdev,
- struct nandfs_super_block *supert, struct nandfs_super_block **super,
- int nsbs)
-{
- int i;
-
- *super = NULL;
- for (i = 0; i < nsbs; i++) {
- if (!nandfs_check_superblock_crc(&fsdev->nd_fsdata, &supert[i]))
- continue;
- DPRINTF(SYNC, ("%s: i %d s_last_cno %jx s_magic %x "
- "s_wtime %jd\n", __func__, i, supert[i].s_last_cno,
- supert[i].s_magic, supert[i].s_wtime));
- if (*super == NULL || supert[i].s_last_cno >
- (*super)->s_last_cno)
- *super = &supert[i];
- }
-
- return (*super != NULL ? 0 : EINVAL);
-}
-
-static int
-nandfs_read_structures_at(struct nandfs_device *fsdev,
- struct nandfs_fsarea *fstp, struct nandfs_fsdata *fsdata,
- struct nandfs_super_block *super)
-{
- struct nandfs_super_block *tsuper, *tsuperd;
- struct buf *bp;
- int error, read_size;
- int i;
- int offset;
-
- offset = fstp->offset;
-
- if (fsdev->nd_erasesize > MAXBSIZE)
- read_size = MAXBSIZE;
- else
- read_size = fsdev->nd_erasesize;
-
- error = bread(fsdev->nd_devvp, btodb(offset), read_size, NOCRED, &bp);
- if (error) {
- printf("couldn't read: %d\n", error);
- brelse(bp);
- fstp->flags |= NANDFS_FSSTOR_FAILED;
- return (error);
- }
-
- tsuper = super;
-
- memcpy(fsdata, bp->b_data, sizeof(struct nandfs_fsdata));
- memcpy(tsuper, (bp->b_data + sizeof(struct nandfs_fsdata)),
- read_size - sizeof(struct nandfs_fsdata));
- brelse(bp);
-
- tsuper += (read_size - sizeof(struct nandfs_fsdata)) /
- sizeof(struct nandfs_super_block);
-
- for (i = 1; i < fsdev->nd_erasesize / read_size; i++) {
- error = bread(fsdev->nd_devvp, btodb(offset + i * read_size),
- read_size, NOCRED, &bp);
- if (error) {
- printf("couldn't read: %d\n", error);
- brelse(bp);
- fstp->flags |= NANDFS_FSSTOR_FAILED;
- return (error);
- }
- memcpy(tsuper, bp->b_data, read_size);
- tsuper += read_size / sizeof(struct nandfs_super_block);
- brelse(bp);
- }
-
- tsuper -= 1;
- fstp->last_used = nandfs_sblocks_in_esize(fsdev) - 1;
- for (tsuperd = super - 1; (tsuper != tsuperd); tsuper -= 1) {
- if (nandfs_is_empty((u_char *)tsuper, sizeof(*tsuper)))
- fstp->last_used--;
- else
- break;
- }
-
- DPRINTF(VOLUMES, ("%s: last_used %d\n", __func__, fstp->last_used));
-
- return (0);
-}
-
-static int
-nandfs_read_structures(struct nandfs_device *fsdev)
-{
- struct nandfs_fsdata *fsdata, *fsdatat;
- struct nandfs_super_block *sblocks, *ssblock;
- u_int nsbs, nfsds, i;
- int error = 0;
- int nrsbs;
-
- nfsds = NANDFS_NFSAREAS;
- nsbs = nandfs_max_sblocks(fsdev);
-
- fsdatat = malloc(sizeof(struct nandfs_fsdata) * nfsds, M_NANDFSTEMP,
- M_WAITOK | M_ZERO);
- sblocks = malloc(sizeof(struct nandfs_super_block) * nsbs, M_NANDFSTEMP,
- M_WAITOK | M_ZERO);
-
- nrsbs = 0;
- for (i = 0; i < NANDFS_NFSAREAS; i++) {
- fsdev->nd_fsarea[i].offset = i * fsdev->nd_erasesize;
- error = nandfs_read_structures_at(fsdev, &fsdev->nd_fsarea[i],
- &fsdatat[i], sblocks + nrsbs);
- if (error)
- continue;
- nrsbs += (fsdev->nd_fsarea[i].last_used + 1);
- if (fsdev->nd_fsarea[fsdev->nd_last_fsarea].last_used >
- fsdev->nd_fsarea[i].last_used)
- fsdev->nd_last_fsarea = i;
- }
-
- if (nrsbs == 0) {
- printf("nandfs: no valid superblocks found\n");
- error = EINVAL;
- goto out;
- }
-
- error = nandfs_select_fsdata(fsdev, fsdatat, &fsdata, nfsds);
- if (error)
- goto out;
- memcpy(&fsdev->nd_fsdata, fsdata, sizeof(struct nandfs_fsdata));
-
- error = nandfs_select_sb(fsdev, sblocks, &ssblock, nsbs);
- if (error)
- goto out;
-
- memcpy(&fsdev->nd_super, ssblock, sizeof(struct nandfs_super_block));
-out:
- free(fsdatat, M_NANDFSTEMP);
- free(sblocks, M_NANDFSTEMP);
-
- if (error == 0)
- DPRINTF(VOLUMES, ("%s: selected sb with w_time %jd "
- "last_pseg %#jx\n", __func__, fsdev->nd_super.s_wtime,
- fsdev->nd_super.s_last_pseg));
-
- return (error);
-}
-
-static void
-nandfs_unmount_base(struct nandfs_device *nandfsdev)
-{
- int error;
-
- if (!nandfsdev)
- return;
-
- /* Remove all our information */
- error = vinvalbuf(nandfsdev->nd_devvp, V_SAVE, 0, 0);
- if (error) {
- /*
- * Flushing buffers failed when fs was umounting, can't do
- * much now, just printf error and continue with umount.
- */
- nandfs_error("%s(): error:%d when umounting FS\n",
- __func__, error);
- }
-
- /* Release the device's system nodes */
- nandfs_release_system_nodes(nandfsdev);
-}
-
-static void
-nandfs_get_ncleanseg(struct nandfs_device *nandfsdev)
-{
- struct nandfs_seg_stat nss;
-
- nandfs_get_seg_stat(nandfsdev, &nss);
- nandfsdev->nd_clean_segs = nss.nss_ncleansegs;
- DPRINTF(VOLUMES, ("nandfs_mount: clean segs: %jx\n",
- (uintmax_t)nandfsdev->nd_clean_segs));
-}
-
-
-static int
-nandfs_mount_base(struct nandfs_device *nandfsdev, struct mount *mp,
- struct nandfs_args *args)
-{
- uint32_t log_blocksize;
- int error;
-
- /* Flush out any old buffers remaining from a previous use. */
- if ((error = vinvalbuf(nandfsdev->nd_devvp, V_SAVE, 0, 0)))
- return (error);
-
- error = nandfs_read_structures(nandfsdev);
- if (error) {
- printf("nandfs: could not get valid filesystem structures\n");
- return (error);
- }
-
- if (nandfsdev->nd_fsdata.f_rev_level != NANDFS_CURRENT_REV) {
- printf("nandfs: unsupported file system revision: %d "
- "(supported is %d).\n", nandfsdev->nd_fsdata.f_rev_level,
- NANDFS_CURRENT_REV);
- return (EINVAL);
- }
-
- if (nandfsdev->nd_fsdata.f_erasesize != nandfsdev->nd_erasesize) {
- printf("nandfs: erasesize mismatch (device %#x, fs %#x)\n",
- nandfsdev->nd_erasesize, nandfsdev->nd_fsdata.f_erasesize);
- return (EINVAL);
- }
-
- /* Get our blocksize */
- log_blocksize = nandfsdev->nd_fsdata.f_log_block_size;
- nandfsdev->nd_blocksize = (uint64_t) 1 << (log_blocksize + 10);
- DPRINTF(VOLUMES, ("%s: blocksize:%x\n", __func__,
- nandfsdev->nd_blocksize));
-
- DPRINTF(VOLUMES, ("%s: accepted super block with cp %#jx\n", __func__,
- (uintmax_t)nandfsdev->nd_super.s_last_cno));
-
- /* Calculate dat structure parameters */
- nandfs_calc_mdt_consts(nandfsdev, &nandfsdev->nd_dat_mdt,
- nandfsdev->nd_fsdata.f_dat_entry_size);
- nandfs_calc_mdt_consts(nandfsdev, &nandfsdev->nd_ifile_mdt,
- nandfsdev->nd_fsdata.f_inode_size);
-
- /* Search for the super root and roll forward when needed */
- if (nandfs_search_super_root(nandfsdev)) {
- printf("Cannot find valid SuperRoot\n");
- return (EINVAL);
- }
-
- nandfsdev->nd_mount_state = nandfsdev->nd_super.s_state;
- if (nandfsdev->nd_mount_state != NANDFS_VALID_FS) {
- printf("FS is seriously damaged, needs repairing\n");
- printf("aborting mount\n");
- return (EINVAL);
- }
-
- /*
- * FS should be ok now. The superblock and the last segsum could be
- * updated from the repair so extract running values again.
- */
- nandfsdev->nd_last_pseg = nandfsdev->nd_super.s_last_pseg;
- nandfsdev->nd_seg_sequence = nandfsdev->nd_super.s_last_seq;
- nandfsdev->nd_seg_num = nandfs_get_segnum_of_block(nandfsdev,
- nandfsdev->nd_last_pseg);
- nandfsdev->nd_next_seg_num = nandfs_get_segnum_of_block(nandfsdev,
- nandfsdev->nd_last_segsum.ss_next);
- nandfsdev->nd_ts.tv_sec = nandfsdev->nd_last_segsum.ss_create;
- nandfsdev->nd_last_cno = nandfsdev->nd_super.s_last_cno;
- nandfsdev->nd_fakevblk = 1;
- /*
- * FIXME: bogus calculation. Should use actual number of usable segments
- * instead of total amount.
- */
- nandfsdev->nd_segs_reserved =
- nandfsdev->nd_fsdata.f_nsegments *
- nandfsdev->nd_fsdata.f_r_segments_percentage / 100;
- nandfsdev->nd_last_ino = NANDFS_USER_INO;
- DPRINTF(VOLUMES, ("%s: last_pseg %#jx last_cno %#jx last_seq %#jx\n"
- "fsdev: last_seg: seq %#jx num %#jx, next_seg_num %#jx "
- "segs_reserved %#jx\n",
- __func__, (uintmax_t)nandfsdev->nd_last_pseg,
- (uintmax_t)nandfsdev->nd_last_cno,
- (uintmax_t)nandfsdev->nd_seg_sequence,
- (uintmax_t)nandfsdev->nd_seg_sequence,
- (uintmax_t)nandfsdev->nd_seg_num,
- (uintmax_t)nandfsdev->nd_next_seg_num,
- (uintmax_t)nandfsdev->nd_segs_reserved));
-
- DPRINTF(VOLUMES, ("nandfs_mount: accepted super root\n"));
-
- /* Create system vnodes for DAT, CP and SEGSUM */
- error = nandfs_create_system_nodes(nandfsdev);
- if (error)
- nandfs_unmount_base(nandfsdev);
-
- nandfs_get_ncleanseg(nandfsdev);
-
- return (error);
-}
-
-static void
-nandfs_unmount_device(struct nandfs_device *nandfsdev)
-{
-
- /* Is there anything? */
- if (nandfsdev == NULL)
- return;
-
- /* Remove the device only if we're the last reference */
- nandfsdev->nd_refcnt--;
- if (nandfsdev->nd_refcnt >= 1)
- return;
-
- MPASS(nandfsdev->nd_syncer == NULL);
- MPASS(nandfsdev->nd_cleaner == NULL);
- MPASS(nandfsdev->nd_free_base == NULL);
-
- /* Unmount our base */
- nandfs_unmount_base(nandfsdev);
-
- /* Remove from our device list */
- SLIST_REMOVE(&nandfs_devices, nandfsdev, nandfs_device, nd_next_device);
-
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(nandfsdev->nd_gconsumer);
- g_topology_unlock();
- PICKUP_GIANT();
-
- DPRINTF(VOLUMES, ("closing device\n"));
-
- /* Clear our mount reference and release device node */
- vrele(nandfsdev->nd_devvp);
-
- dev_rel(nandfsdev->nd_devvp->v_rdev);
-
- /* Free our device info */
- cv_destroy(&nandfsdev->nd_sync_cv);
- mtx_destroy(&nandfsdev->nd_sync_mtx);
- cv_destroy(&nandfsdev->nd_clean_cv);
- mtx_destroy(&nandfsdev->nd_clean_mtx);
- mtx_destroy(&nandfsdev->nd_mutex);
- lockdestroy(&nandfsdev->nd_seg_const);
- free(nandfsdev, M_NANDFSMNT);
-}
-
-static int
-nandfs_check_mounts(struct nandfs_device *nandfsdev, struct mount *mp,
- struct nandfs_args *args)
-{
- struct nandfsmount *nmp;
- uint64_t last_cno;
-
- /* no double-mounting of the same checkpoint */
- STAILQ_FOREACH(nmp, &nandfsdev->nd_mounts, nm_next_mount) {
- if (nmp->nm_mount_args.cpno == args->cpno)
- return (EBUSY);
- }
-
- /* Allow readonly mounts without questioning here */
- if (mp->mnt_flag & MNT_RDONLY)
- return (0);
-
- /* Read/write mount */
- STAILQ_FOREACH(nmp, &nandfsdev->nd_mounts, nm_next_mount) {
- /* Only one RW mount on this device! */
- if ((nmp->nm_vfs_mountp->mnt_flag & MNT_RDONLY)==0)
- return (EROFS);
- /* RDONLY on last mountpoint is device busy */
- last_cno = nmp->nm_nandfsdev->nd_super.s_last_cno;
- if (nmp->nm_mount_args.cpno == last_cno)
- return (EBUSY);
- }
-
- /* OK for now */
- return (0);
-}
-
-static int
-nandfs_mount_device(struct vnode *devvp, struct mount *mp,
- struct nandfs_args *args, struct nandfs_device **nandfsdev_p)
-{
- struct nandfs_device *nandfsdev;
- struct g_provider *pp;
- struct g_consumer *cp;
- struct cdev *dev;
- uint32_t erasesize;
- int error, size;
- int ronly;
-
- DPRINTF(VOLUMES, ("Mounting NANDFS device\n"));
-
- ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
-
- /* Look up device in our nandfs_mountpoints */
- *nandfsdev_p = NULL;
- SLIST_FOREACH(nandfsdev, &nandfs_devices, nd_next_device)
- if (nandfsdev->nd_devvp == devvp)
- break;
-
- if (nandfsdev) {
- DPRINTF(VOLUMES, ("device already mounted\n"));
- error = nandfs_check_mounts(nandfsdev, mp, args);
- if (error)
- return error;
- nandfsdev->nd_refcnt++;
- *nandfsdev_p = nandfsdev;
-
- if (!ronly) {
- DROP_GIANT();
- g_topology_lock();
- error = g_access(nandfsdev->nd_gconsumer, 0, 1, 0);
- g_topology_unlock();
- PICKUP_GIANT();
- }
- return (error);
- }
-
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
- dev = devvp->v_rdev;
- dev_ref(dev);
- DROP_GIANT();
- g_topology_lock();
- error = g_vfs_open(devvp, &cp, "nandfs", ronly ? 0 : 1);
- pp = g_dev_getprovider(dev);
- g_topology_unlock();
- PICKUP_GIANT();
- VOP_UNLOCK(devvp, 0);
- if (error) {
- dev_rel(dev);
- return (error);
- }
-
- nandfsdev = malloc(sizeof(struct nandfs_device), M_NANDFSMNT, M_WAITOK | M_ZERO);
-
- /* Initialise */
- nandfsdev->nd_refcnt = 1;
- nandfsdev->nd_devvp = devvp;
- nandfsdev->nd_syncing = 0;
- nandfsdev->nd_cleaning = 0;
- nandfsdev->nd_gconsumer = cp;
- cv_init(&nandfsdev->nd_sync_cv, "nandfssync");
- mtx_init(&nandfsdev->nd_sync_mtx, "nffssyncmtx", NULL, MTX_DEF);
- cv_init(&nandfsdev->nd_clean_cv, "nandfsclean");
- mtx_init(&nandfsdev->nd_clean_mtx, "nffscleanmtx", NULL, MTX_DEF);
- mtx_init(&nandfsdev->nd_mutex, "nandfsdev lock", NULL, MTX_DEF);
- lockinit(&nandfsdev->nd_seg_const, PVFS, "nffssegcon", VLKTIMEOUT,
- LK_CANRECURSE);
- STAILQ_INIT(&nandfsdev->nd_mounts);
-
- nandfsdev->nd_devsize = pp->mediasize;
- nandfsdev->nd_devblocksize = pp->sectorsize;
-
- size = sizeof(erasesize);
- error = g_io_getattr("NAND::blocksize", nandfsdev->nd_gconsumer, &size,
- &erasesize);
- if (error) {
- DPRINTF(VOLUMES, ("couldn't get erasesize: %d\n", error));
-
- if (error == ENOIOCTL || error == EOPNOTSUPP) {
- /*
- * We conclude that this is not NAND storage
- */
- erasesize = NANDFS_DEF_ERASESIZE;
- } else {
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(nandfsdev->nd_gconsumer);
- g_topology_unlock();
- PICKUP_GIANT();
- dev_rel(dev);
- free(nandfsdev, M_NANDFSMNT);
- return (error);
- }
- }
- nandfsdev->nd_erasesize = erasesize;
-
- DPRINTF(VOLUMES, ("%s: erasesize %x\n", __func__,
- nandfsdev->nd_erasesize));
-
- /* Register nandfs_device in list */
- SLIST_INSERT_HEAD(&nandfs_devices, nandfsdev, nd_next_device);
-
- error = nandfs_mount_base(nandfsdev, mp, args);
- if (error) {
- /* Remove all our information */
- nandfs_unmount_device(nandfsdev);
- return (EINVAL);
- }
-
- nandfsdev->nd_maxfilesize = nandfs_get_maxfilesize(nandfsdev);
-
- *nandfsdev_p = nandfsdev;
- DPRINTF(VOLUMES, ("NANDFS device mounted ok\n"));
-
- return (0);
-}
-
-static int
-nandfs_mount_checkpoint(struct nandfsmount *nmp)
-{
- struct nandfs_cpfile_header *cphdr;
- struct nandfs_checkpoint *cp;
- struct nandfs_inode ifile_inode;
- struct nandfs_node *cp_node;
- struct buf *bp;
- uint64_t ncp, nsn, cpno, fcpno, blocknr, last_cno;
- uint32_t off, dlen;
- int cp_per_block, error;
-
- cpno = nmp->nm_mount_args.cpno;
- if (cpno == 0)
- cpno = nmp->nm_nandfsdev->nd_super.s_last_cno;
-
- DPRINTF(VOLUMES, ("%s: trying to mount checkpoint number %"PRIu64"\n",
- __func__, cpno));
-
- cp_node = nmp->nm_nandfsdev->nd_cp_node;
-
- VOP_LOCK(NTOV(cp_node), LK_SHARED);
- /* Get cpfile header from 1st block of cp file */
- error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- VOP_UNLOCK(NTOV(cp_node), 0);
- return (error);
- }
-
- cphdr = (struct nandfs_cpfile_header *) bp->b_data;
- ncp = cphdr->ch_ncheckpoints;
- nsn = cphdr->ch_nsnapshots;
-
- brelse(bp);
-
- DPRINTF(VOLUMES, ("mount_nandfs: checkpoint header read in\n"));
- DPRINTF(VOLUMES, ("\tNumber of checkpoints %"PRIu64"\n", ncp));
- DPRINTF(VOLUMES, ("\tNumber of snapshots %"PRIu64"\n", nsn));
-
- /* Read in our specified checkpoint */
- dlen = nmp->nm_nandfsdev->nd_fsdata.f_checkpoint_size;
- cp_per_block = nmp->nm_nandfsdev->nd_blocksize / dlen;
-
- fcpno = cpno + NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET - 1;
- blocknr = fcpno / cp_per_block;
- off = (fcpno % cp_per_block) * dlen;
- error = nandfs_bread(cp_node, blocknr, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- VOP_UNLOCK(NTOV(cp_node), 0);
- printf("mount_nandfs: couldn't read cp block %"PRIu64"\n",
- fcpno);
- return (EINVAL);
- }
-
- /* Needs to be a valid checkpoint */
- cp = (struct nandfs_checkpoint *) ((uint8_t *) bp->b_data + off);
- if (cp->cp_flags & NANDFS_CHECKPOINT_INVALID) {
- printf("mount_nandfs: checkpoint marked invalid\n");
- brelse(bp);
- VOP_UNLOCK(NTOV(cp_node), 0);
- return (EINVAL);
- }
-
- /* Is this really the checkpoint we want? */
- if (cp->cp_cno != cpno) {
- printf("mount_nandfs: checkpoint file corrupt? "
- "expected cpno %"PRIu64", found cpno %"PRIu64"\n",
- cpno, cp->cp_cno);
- brelse(bp);
- VOP_UNLOCK(NTOV(cp_node), 0);
- return (EINVAL);
- }
-
- /* Check if it's a snapshot ! */
- last_cno = nmp->nm_nandfsdev->nd_super.s_last_cno;
- if (cpno != last_cno) {
- /* Only allow snapshots if not mounting on the last cp */
- if ((cp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT) == 0) {
- printf( "mount_nandfs: checkpoint %"PRIu64" is not a "
- "snapshot\n", cpno);
- brelse(bp);
- VOP_UNLOCK(NTOV(cp_node), 0);
- return (EINVAL);
- }
- }
-
- ifile_inode = cp->cp_ifile_inode;
- brelse(bp);
-
- /* Get ifile inode */
- error = nandfs_get_node_raw(nmp->nm_nandfsdev, NULL, NANDFS_IFILE_INO,
- &ifile_inode, &nmp->nm_ifile_node);
- if (error) {
- printf("mount_nandfs: can't read ifile node\n");
- VOP_UNLOCK(NTOV(cp_node), 0);
- return (EINVAL);
- }
-
- NANDFS_SET_SYSTEMFILE(NTOV(nmp->nm_ifile_node));
- VOP_UNLOCK(NTOV(cp_node), 0);
- /* Get root node? */
-
- return (0);
-}
-
-static void
-free_nandfs_mountinfo(struct mount *mp)
-{
- struct nandfsmount *nmp = VFSTONANDFS(mp);
-
- if (nmp == NULL)
- return;
-
- free(nmp, M_NANDFSMNT);
-}
-
-void
-nandfs_wakeup_wait_sync(struct nandfs_device *nffsdev, int reason)
-{
- char *reasons[] = {
- "umount",
- "vfssync",
- "bdflush",
- "fforce",
- "fsync",
- "ro_upd"
- };
-
- DPRINTF(SYNC, ("%s: %s\n", __func__, reasons[reason]));
- mtx_lock(&nffsdev->nd_sync_mtx);
- if (nffsdev->nd_syncing)
- cv_wait(&nffsdev->nd_sync_cv, &nffsdev->nd_sync_mtx);
- if (reason == SYNCER_UMOUNT)
- nffsdev->nd_syncer_exit = 1;
- nffsdev->nd_syncing = 1;
- wakeup(&nffsdev->nd_syncing);
- cv_wait(&nffsdev->nd_sync_cv, &nffsdev->nd_sync_mtx);
-
- mtx_unlock(&nffsdev->nd_sync_mtx);
-}
-
-static void
-nandfs_gc_finished(struct nandfs_device *nffsdev, int exit)
-{
- int error;
-
- mtx_lock(&nffsdev->nd_sync_mtx);
- nffsdev->nd_syncing = 0;
- DPRINTF(SYNC, ("%s: cleaner finish\n", __func__));
- cv_broadcast(&nffsdev->nd_sync_cv);
- mtx_unlock(&nffsdev->nd_sync_mtx);
- if (!exit) {
- error = tsleep(&nffsdev->nd_syncing, PRIBIO, "-",
- hz * nandfs_sync_interval);
- DPRINTF(SYNC, ("%s: cleaner waked up: %d\n",
- __func__, error));
- }
-}
-
-static void
-nandfs_syncer(struct nandfsmount *nmp)
-{
- struct nandfs_device *nffsdev;
- struct mount *mp;
- int flags, error;
-
- mp = nmp->nm_vfs_mountp;
- nffsdev = nmp->nm_nandfsdev;
- tsleep(&nffsdev->nd_syncing, PRIBIO, "-", hz * nandfs_sync_interval);
-
- while (!nffsdev->nd_syncer_exit) {
- DPRINTF(SYNC, ("%s: syncer run\n", __func__));
- nffsdev->nd_syncing = 1;
-
- flags = (nmp->nm_flags & (NANDFS_FORCE_SYNCER | NANDFS_UMOUNT));
-
- error = nandfs_segment_constructor(nmp, flags);
- if (error)
- nandfs_error("%s: error:%d when creating segments\n",
- __func__, error);
-
- nmp->nm_flags &= ~flags;
-
- nandfs_gc_finished(nffsdev, 0);
- }
-
- MPASS(nffsdev->nd_cleaner == NULL);
- error = nandfs_segment_constructor(nmp,
- NANDFS_FORCE_SYNCER | NANDFS_UMOUNT);
- if (error)
- nandfs_error("%s: error:%d when creating segments\n",
- __func__, error);
- nandfs_gc_finished(nffsdev, 1);
- nffsdev->nd_syncer = NULL;
- MPASS(nffsdev->nd_free_base == NULL);
-
- DPRINTF(SYNC, ("%s: exiting\n", __func__));
- kthread_exit();
-}
-
-static int
-start_syncer(struct nandfsmount *nmp)
-{
- int error;
-
- MPASS(nmp->nm_nandfsdev->nd_syncer == NULL);
-
- DPRINTF(SYNC, ("%s: start syncer\n", __func__));
-
- nmp->nm_nandfsdev->nd_syncer_exit = 0;
-
- error = kthread_add((void(*)(void *))nandfs_syncer, nmp, NULL,
- &nmp->nm_nandfsdev->nd_syncer, 0, 0, "nandfs_syncer");
-
- if (error)
- printf("nandfs: could not start syncer: %d\n", error);
-
- return (error);
-}
-
-static int
-stop_syncer(struct nandfsmount *nmp)
-{
-
- MPASS(nmp->nm_nandfsdev->nd_syncer != NULL);
-
- nandfs_wakeup_wait_sync(nmp->nm_nandfsdev, SYNCER_UMOUNT);
-
- DPRINTF(SYNC, ("%s: stop syncer\n", __func__));
- return (0);
-}
-
-/*
- * Mount null layer
- */
-static int
-nandfs_mount(struct mount *mp)
-{
- struct nandfsmount *nmp;
- struct vnode *devvp;
- struct nameidata nd;
- struct vfsoptlist *opts;
- struct thread *td;
- char *from;
- int error = 0, flags;
-
- DPRINTF(VOLUMES, ("%s: mp = %p\n", __func__, (void *)mp));
-
- td = curthread;
- opts = mp->mnt_optnew;
-
- if (vfs_filteropt(opts, nandfs_opts))
- return (EINVAL);
-
- /*
- * Update is a no-op
- */
- if (mp->mnt_flag & MNT_UPDATE) {
- nmp = VFSTONANDFS(mp);
- if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
- return (error);
- }
- if (!(nmp->nm_ronly) && vfs_flagopt(opts, "ro", NULL, 0)) {
- vn_start_write(NULL, &mp, V_WAIT);
- error = VFS_SYNC(mp, MNT_WAIT);
- if (error)
- return (error);
- vn_finished_write(mp);
-
- flags = WRITECLOSE;
- if (mp->mnt_flag & MNT_FORCE)
- flags |= FORCECLOSE;
-
- nandfs_wakeup_wait_sync(nmp->nm_nandfsdev,
- SYNCER_ROUPD);
- error = vflush(mp, 0, flags, td);
- if (error)
- return (error);
-
- nandfs_stop_cleaner(nmp->nm_nandfsdev);
- stop_syncer(nmp);
- DROP_GIANT();
- g_topology_lock();
- g_access(nmp->nm_nandfsdev->nd_gconsumer, 0, -1, 0);
- g_topology_unlock();
- PICKUP_GIANT();
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_RDONLY;
- MNT_IUNLOCK(mp);
- nmp->nm_ronly = 1;
-
- } else if ((nmp->nm_ronly) &&
- !vfs_flagopt(opts, "ro", NULL, 0)) {
- /*
- * Don't allow read-write snapshots.
- */
- if (nmp->nm_mount_args.cpno != 0)
- return (EROFS);
- /*
- * If upgrade to read-write by non-root, then verify
- * that user has necessary permissions on the device.
- */
- devvp = nmp->nm_nandfsdev->nd_devvp;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
- error = VOP_ACCESS(devvp, VREAD | VWRITE,
- td->td_ucred, td);
- if (error) {
- error = priv_check(td, PRIV_VFS_MOUNT_PERM);
- if (error) {
- VOP_UNLOCK(devvp, 0);
- return (error);
- }
- }
-
- VOP_UNLOCK(devvp, 0);
- DROP_GIANT();
- g_topology_lock();
- error = g_access(nmp->nm_nandfsdev->nd_gconsumer, 0, 1,
- 0);
- g_topology_unlock();
- PICKUP_GIANT();
- if (error)
- return (error);
-
- MNT_ILOCK(mp);
- mp->mnt_flag &= ~MNT_RDONLY;
- MNT_IUNLOCK(mp);
- error = start_syncer(nmp);
- if (error == 0)
- error = nandfs_start_cleaner(nmp->nm_nandfsdev);
- if (error) {
- DROP_GIANT();
- g_topology_lock();
- g_access(nmp->nm_nandfsdev->nd_gconsumer, 0, -1,
- 0);
- g_topology_unlock();
- PICKUP_GIANT();
- return (error);
- }
-
- nmp->nm_ronly = 0;
- }
- return (0);
- }
-
- from = vfs_getopts(opts, "from", &error);
- if (error)
- return (error);
-
- /*
- * Find device node
- */
- NDINIT(&nd, LOOKUP, FOLLOW|LOCKLEAF, UIO_SYSSPACE, from, curthread);
- error = namei(&nd);
- if (error)
- return (error);
- NDFREE(&nd, NDF_ONLY_PNBUF);
-
- devvp = nd.ni_vp;
-
- if (!vn_isdisk(devvp, &error)) {
- vput(devvp);
- return (error);
- }
-
- /* Check the access rights on the mount device */
- error = VOP_ACCESS(devvp, VREAD, curthread->td_ucred, curthread);
- if (error)
- error = priv_check(curthread, PRIV_VFS_MOUNT_PERM);
- if (error) {
- vput(devvp);
- return (error);
- }
-
- vfs_getnewfsid(mp);
-
- error = nandfs_mountfs(devvp, mp);
- if (error)
- return (error);
- vfs_mountedfrom(mp, from);
-
- return (0);
-}
-
-static int
-nandfs_mountfs(struct vnode *devvp, struct mount *mp)
-{
- struct nandfsmount *nmp = NULL;
- struct nandfs_args *args = NULL;
- struct nandfs_device *nandfsdev;
- char *from;
- int error, ronly;
- char *cpno;
-
- ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
-
- if (devvp->v_rdev->si_iosize_max != 0)
- mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
- VOP_UNLOCK(devvp, 0);
-
- if (mp->mnt_iosize_max > MAXPHYS)
- mp->mnt_iosize_max = MAXPHYS;
-
- from = vfs_getopts(mp->mnt_optnew, "from", &error);
- if (error)
- goto error;
-
- error = vfs_getopt(mp->mnt_optnew, "snap", (void **)&cpno, NULL);
- if (error == ENOENT)
- cpno = NULL;
- else if (error)
- goto error;
-
- args = (struct nandfs_args *)malloc(sizeof(struct nandfs_args),
- M_NANDFSMNT, M_WAITOK | M_ZERO);
-
- if (cpno != NULL)
- args->cpno = strtoul(cpno, (char **)NULL, 10);
- else
- args->cpno = 0;
- args->fspec = from;
-
- if (args->cpno != 0 && !ronly) {
- error = EROFS;
- goto error;
- }
-
- printf("WARNING: NANDFS is considered to be a highly experimental "
- "feature in FreeBSD.\n");
-
- error = nandfs_mount_device(devvp, mp, args, &nandfsdev);
- if (error)
- goto error;
-
- nmp = (struct nandfsmount *) malloc(sizeof(struct nandfsmount),
- M_NANDFSMNT, M_WAITOK | M_ZERO);
-
- mp->mnt_data = nmp;
- nmp->nm_vfs_mountp = mp;
- nmp->nm_ronly = ronly;
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_LOCAL;
- mp->mnt_kern_flag |= MNTK_USES_BCACHE;
- MNT_IUNLOCK(mp);
- nmp->nm_nandfsdev = nandfsdev;
- /* Add our mountpoint */
- STAILQ_INSERT_TAIL(&nandfsdev->nd_mounts, nmp, nm_next_mount);
-
- if (args->cpno > nandfsdev->nd_last_cno) {
- printf("WARNING: supplied checkpoint number (%jd) is greater "
- "than last known checkpoint on filesystem (%jd). Mounting"
- " checkpoint %jd\n", (uintmax_t)args->cpno,
- (uintmax_t)nandfsdev->nd_last_cno,
- (uintmax_t)nandfsdev->nd_last_cno);
- args->cpno = nandfsdev->nd_last_cno;
- }
-
- /* Setting up other parameters */
- nmp->nm_mount_args = *args;
- free(args, M_NANDFSMNT);
- error = nandfs_mount_checkpoint(nmp);
- if (error) {
- nandfs_unmount(mp, MNT_FORCE);
- goto unmounted;
- }
-
- if (!ronly) {
- error = start_syncer(nmp);
- if (error == 0)
- error = nandfs_start_cleaner(nmp->nm_nandfsdev);
- if (error)
- nandfs_unmount(mp, MNT_FORCE);
- }
-
- return (0);
-
-error:
- if (args != NULL)
- free(args, M_NANDFSMNT);
-
- if (nmp != NULL) {
- free(nmp, M_NANDFSMNT);
- mp->mnt_data = NULL;
- }
-unmounted:
- return (error);
-}
-
-static int
-nandfs_unmount(struct mount *mp, int mntflags)
-{
- struct nandfs_device *nandfsdev;
- struct nandfsmount *nmp;
- int error;
- int flags = 0;
-
- DPRINTF(VOLUMES, ("%s: mp = %p\n", __func__, (void *)mp));
-
- if (mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
-
- nmp = mp->mnt_data;
- nandfsdev = nmp->nm_nandfsdev;
-
- error = vflush(mp, 0, flags | SKIPSYSTEM, curthread);
- if (error)
- return (error);
-
- if (!(nmp->nm_ronly)) {
- nandfs_stop_cleaner(nandfsdev);
- stop_syncer(nmp);
- }
-
- if (nmp->nm_ifile_node)
- NANDFS_UNSET_SYSTEMFILE(NTOV(nmp->nm_ifile_node));
-
- /* Remove our mount point */
- STAILQ_REMOVE(&nandfsdev->nd_mounts, nmp, nandfsmount, nm_next_mount);
-
- /* Unmount the device itself when we're the last one */
- nandfs_unmount_device(nandfsdev);
-
- free_nandfs_mountinfo(mp);
-
- /*
- * Finally, throw away the null_mount structure
- */
- mp->mnt_data = 0;
- MNT_ILOCK(mp);
- mp->mnt_flag &= ~MNT_LOCAL;
- MNT_IUNLOCK(mp);
-
- return (0);
-}
-
-static int
-nandfs_statfs(struct mount *mp, struct statfs *sbp)
-{
- struct nandfsmount *nmp;
- struct nandfs_device *nandfsdev;
- struct nandfs_fsdata *fsdata;
- struct nandfs_super_block *sb;
- struct nandfs_block_group_desc *groups;
- struct nandfs_node *ifile;
- struct nandfs_mdt *mdt;
- struct buf *bp;
- int i, error;
- uint32_t entries_per_group;
- uint64_t files = 0;
-
- nmp = mp->mnt_data;
- nandfsdev = nmp->nm_nandfsdev;
- fsdata = &nandfsdev->nd_fsdata;
- sb = &nandfsdev->nd_super;
- ifile = nmp->nm_ifile_node;
- mdt = &nandfsdev->nd_ifile_mdt;
- entries_per_group = mdt->entries_per_group;
-
- VOP_LOCK(NTOV(ifile), LK_SHARED);
- error = nandfs_bread(ifile, 0, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- VOP_UNLOCK(NTOV(ifile), 0);
- return (error);
- }
-
- groups = (struct nandfs_block_group_desc *)bp->b_data;
-
- for (i = 0; i < mdt->groups_per_desc_block; i++)
- files += (entries_per_group - groups[i].bg_nfrees);
-
- brelse(bp);
- VOP_UNLOCK(NTOV(ifile), 0);
-
- sbp->f_bsize = nandfsdev->nd_blocksize;
- sbp->f_iosize = sbp->f_bsize;
- sbp->f_blocks = fsdata->f_blocks_per_segment * fsdata->f_nsegments;
- sbp->f_bfree = sb->s_free_blocks_count;
- sbp->f_bavail = sbp->f_bfree;
- sbp->f_files = files;
- sbp->f_ffree = 0;
- return (0);
-}
-
-static int
-nandfs_root(struct mount *mp, int flags, struct vnode **vpp)
-{
- struct nandfsmount *nmp = VFSTONANDFS(mp);
- struct nandfs_node *node;
- int error;
-
- error = nandfs_get_node(nmp, NANDFS_ROOT_INO, &node);
- if (error)
- return (error);
-
- KASSERT(NTOV(node)->v_vflag & VV_ROOT,
- ("root_vp->v_vflag & VV_ROOT"));
-
- *vpp = NTOV(node);
-
- return (error);
-}
-
-static int
-nandfs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
-{
- struct nandfsmount *nmp = VFSTONANDFS(mp);
- struct nandfs_node *node;
- int error;
-
- error = nandfs_get_node(nmp, ino, &node);
- if (node)
- *vpp = NTOV(node);
-
- return (error);
-}
-
-static int
-nandfs_sync(struct mount *mp, int waitfor)
-{
- struct nandfsmount *nmp = VFSTONANDFS(mp);
-
- DPRINTF(SYNC, ("%s: mp %p waitfor %d\n", __func__, mp, waitfor));
-
- /*
- * XXX: A hack to be removed soon
- */
- if (waitfor == MNT_LAZY)
- return (0);
- if (waitfor == MNT_SUSPEND)
- return (0);
- nandfs_wakeup_wait_sync(nmp->nm_nandfsdev, SYNCER_VFS_SYNC);
- return (0);
-}
-
-static struct vfsops nandfs_vfsops = {
- .vfs_init = nandfs_init,
- .vfs_mount = nandfs_mount,
- .vfs_root = nandfs_root,
- .vfs_statfs = nandfs_statfs,
- .vfs_uninit = nandfs_uninit,
- .vfs_unmount = nandfs_unmount,
- .vfs_vget = nandfs_vget,
- .vfs_sync = nandfs_sync,
-};
-
-VFS_SET(nandfs_vfsops, nandfs, VFCF_LOOPBACK);
diff --git a/sys/fs/nandfs/nandfs_vnops.c b/sys/fs/nandfs/nandfs_vnops.c
deleted file mode 100644
index 5027d6adbbc1..000000000000
--- a/sys/fs/nandfs/nandfs_vnops.c
+++ /dev/null
@@ -1,2454 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2010-2012 Semihalf
- * Copyright (c) 2008, 2009 Reinoud Zandijk
- * 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 ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * From: NetBSD: nilfs_vnops.c,v 1.2 2009/08/26 03:40:48 elad
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/lockf.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/sysctl.h>
-#include <sys/unistd.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/bio.h>
-#include <sys/fcntl.h>
-#include <sys/dirent.h>
-#include <sys/rwlock.h>
-#include <sys/stat.h>
-#include <sys/priv.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-#include <vm/vnode_pager.h>
-
-#include <machine/_inttypes.h>
-
-#include <fs/nandfs/nandfs_mount.h>
-#include <fs/nandfs/nandfs.h>
-#include <fs/nandfs/nandfs_subr.h>
-
-extern uma_zone_t nandfs_node_zone;
-static void nandfs_read_filebuf(struct nandfs_node *, struct buf *);
-static void nandfs_itimes_locked(struct vnode *);
-static int nandfs_truncate(struct vnode *, uint64_t);
-
-static vop_pathconf_t nandfs_pathconf;
-
-#define UPDATE_CLOSE 0
-#define UPDATE_WAIT 0
-
-static int
-nandfs_inactive(struct vop_inactive_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nandfs_node *node = VTON(vp);
- int error = 0;
-
- DPRINTF(VNCALL, ("%s: vp:%p node:%p\n", __func__, vp, node));
-
- if (node == NULL) {
- DPRINTF(NODE, ("%s: inactive NULL node\n", __func__));
- return (0);
- }
-
- if (node->nn_inode.i_mode != 0 && !(node->nn_inode.i_links_count)) {
- nandfs_truncate(vp, 0);
- error = nandfs_node_destroy(node);
- if (error)
- nandfs_error("%s: destroy node: %p\n", __func__, node);
- node->nn_flags = 0;
- vrecycle(vp);
- }
-
- return (error);
-}
-
-static int
-nandfs_reclaim(struct vop_reclaim_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nandfs_node *nandfs_node = VTON(vp);
- struct nandfs_device *fsdev = nandfs_node->nn_nandfsdev;
- uint64_t ino = nandfs_node->nn_ino;
-
- DPRINTF(VNCALL, ("%s: vp:%p node:%p\n", __func__, vp, nandfs_node));
-
- /* Invalidate all entries to a particular vnode. */
- cache_purge(vp);
-
- /* Destroy the vm object and flush associated pages. */
- vnode_destroy_vobject(vp);
-
- /* Remove from vfs hash if not system vnode */
- if