svn commit: r233975 - in projects/nand: include sys/dev/nand
Grzegorz Bernacki
gber at FreeBSD.org
Sat Apr 7 04:22:48 UTC 2012
Author: gber
Date: Sat Apr 7 04:22:46 2012
New Revision: 233975
URL: http://svn.freebsd.org/changeset/base/233975
Log:
nand: Follow-up to latest changes in geom
Obtained from: Semihalf
Supported by: FreeBSD Foundation, Juniper Networks
Added:
projects/nand/sys/dev/nand/nand_dev.h
Deleted:
projects/nand/sys/dev/nand/nand_cdev.h
Modified:
projects/nand/include/Makefile
projects/nand/sys/dev/nand/nand.c
projects/nand/sys/dev/nand/nand.h
projects/nand/sys/dev/nand/nand_cdev.c
projects/nand/sys/dev/nand/nand_generic.c
projects/nand/sys/dev/nand/nand_geom.c
projects/nand/sys/dev/nand/nandsim.c
projects/nand/sys/dev/nand/nandsim_chip.c
Modified: projects/nand/include/Makefile
==============================================================================
--- projects/nand/include/Makefile Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/include/Makefile Sat Apr 7 04:22:46 2012 (r233975)
@@ -172,7 +172,7 @@ copies:
cd ${.CURDIR}/../sys/dev/nand; \
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 nandsim.h \
${DESTDIR}${INCLUDEDIR}/dev/nand; \
- ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 nand_cdev.h \
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 nand_dev.h \
${DESTDIR}${INCLUDEDIR}/dev/nand
.endif
cd ${.CURDIR}/../sys/contrib/altq/altq; \
@@ -249,7 +249,7 @@ symlinks:
done
.if ${MK_NAND} != "no"
cd ${.CURDIR}/../sys/dev/nand; \
- for h in nandsim.h nand_cdev.h; do \
+ for h in nandsim.h nand_dev.h; do \
ln -fs ../../../../sys/dev/nand/$$h \
${DESTDIR}${INCLUDEDIR}/dev/nand; \
done
Modified: projects/nand/sys/dev/nand/nand.c
==============================================================================
--- projects/nand/sys/dev/nand/nand.c Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/sys/dev/nand/nand.c Sat Apr 7 04:22:46 2012 (r233975)
@@ -106,7 +106,7 @@ nand_init(struct nand_softc *nand, devic
if (ecc_mode == NAND_ECC_SOFT) {
nand->ecc.eccbytes = SOFTECC_BYTES;
nand->ecc.eccsize = SOFTECC_SIZE;
- } else if (ecc_mode != NAND_ECC_NONE){
+ } else if (ecc_mode != NAND_ECC_NONE) {
nand->ecc.eccbytes = ecc_bytes;
nand->ecc.eccsize = ecc_size;
if (eccposition)
@@ -153,7 +153,7 @@ nand_set_params(struct nand_chip *chip,
chip->t_ccs = 0;
if (params->flags & NAND_16_BIT)
- chip->flags |= NAND_16_BIT;
+ chip->flags |= NAND_16_BIT;
}
int
@@ -390,9 +390,9 @@ correct_ecc(uint8_t *buf, uint8_t *calc_
addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2);
addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) |
- (BIT5(ecc2) << 5) | (BIT7(ecc2) << 6);
+ (BIT5(ecc2) << 5) | (BIT7(ecc2) << 6);
addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) |
- (BIT5(ecc1) << 9) | (BIT7(ecc1) << 10);
+ (BIT5(ecc1) << 9) | (BIT7(ecc1) << 10);
onesnum = 0;
while (ecc0 || ecc1 || ecc2) {
@@ -432,7 +432,7 @@ nand_softecc_get(device_t dev, uint8_t *
int i = 0, j = 0;
for (; i < (steps * SOFTECC_BYTES);
- i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
+ i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
calculate_ecc(&buf[j], &ecc[i]);
}
@@ -447,7 +447,7 @@ nand_softecc_correct(device_t dev, uint8
int i = 0, j = 0, ret = 0;
for (i = 0; i < (steps * SOFTECC_BYTES);
- i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
+ i += SOFTECC_BYTES, j += SOFTECC_SIZE) {
ret += correct_ecc(&buf[j], &calcecc[i], &readecc[i]);
if (ret < 0)
return (ret);
@@ -677,7 +677,7 @@ nand_prog_pages(struct nand_chip *chip,
oob[eccpos[i]] = eccd->ecccalculated[i];
if (NAND_PROGRAM_OOB(chip->dev, page, oob,
- cg->oob_size, 0)) {
+ cg->oob_size, 0)) {
err = ENXIO;
break;
}
@@ -746,7 +746,7 @@ nand_prog_pages_raw(struct nand_chip *ch
if (end)
retval = NAND_PROGRAM_PAGE(chip->dev, page, ptr, end, 0);
-
+
NANDBUS_UNLOCK(nandbus);
return (retval);
Modified: projects/nand/sys/dev/nand/nand.h
==============================================================================
--- projects/nand/sys/dev/nand/nand.h Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/sys/dev/nand/nand.h Sat Apr 7 04:22:46 2012 (r233975)
@@ -40,7 +40,7 @@
#include <sys/mutex.h>
#include <sys/malloc.h>
-#include <dev/nand/nand_cdev.h>
+#include <dev/nand/nand_dev.h>
MALLOC_DECLARE(M_NAND);
@@ -120,10 +120,6 @@ MALLOC_DECLARE(M_NAND);
#define ECC_ERROR_ECC (-1)
#define ECC_UNCORRECTABLE (-2)
-/* NAND BIO operations */
-#define BIO_READOOB BIO_CMD0
-#define BIO_WRITEOOB BIO_CMD1
-
#define NAND_MAN_SAMSUNG 0xec
#define NAND_MAN_HYNIX 0xad
#define NAND_MAN_STMICRO 0x20
@@ -290,8 +286,8 @@ struct nand_chip {
struct nand_ops *ops;
struct cdev *cdev;
- struct gnand *disk;
- struct gnand *rdisk;
+ 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 */
Modified: projects/nand/sys/dev/nand/nand_cdev.c
==============================================================================
--- projects/nand/sys/dev/nand/nand_cdev.c Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/sys/dev/nand/nand_cdev.c Sat Apr 7 04:22:46 2012 (r233975)
@@ -1,412 +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.
- */
-
-#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_cdev.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);
-
- 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) == BIO_READ ? "READ" : "WRITE",
- chip->num, chip);
-
- if ((bp->bio_cmd & BIO_READ) == 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 nand_oob_rw *oob_rw = NULL;
- struct nand_raw_rw *raw_rw = NULL;
- device_t nandbus;
- uint8_t *buf = NULL;
- int ret = 0;
- uint8_t status;
-
- chip = (struct nand_chip *)dev->si_drv1;
- nandbus = device_get_parent(chip->dev);
-
- if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) {
- raw_rw = (struct nand_raw_rw *)data;
- buf = malloc(raw_rw->len, M_NAND, M_WAITOK);
- }
- 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:
- oob_rw = (struct nand_oob_rw *)data;
- ret = copyin(oob_rw->data, buf, oob_rw->len);
- if (ret)
- break;
- ret = nand_prog_pages_raw(chip, raw_rw->off, buf,
- raw_rw->len);
- break;
-
- case NAND_IO_RAW_READ:
- oob_rw = (struct nand_oob_rw *)data;
- ret = nand_read_pages_raw(chip, raw_rw->off, buf,
- raw_rw->len);
- if (ret)
- break;
- ret = copyout(buf, oob_rw->data, oob_rw->len);
- 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);
-}
Added: projects/nand/sys/dev/nand/nand_dev.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/nand/sys/dev/nand/nand_dev.h Sat Apr 7 04:22:46 2012 (r233975)
@@ -0,0 +1,90 @@
+/*-
+ * 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_ */
Modified: projects/nand/sys/dev/nand/nand_generic.c
==============================================================================
--- projects/nand/sys/dev/nand/nand_generic.c Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/sys/dev/nand/nand_generic.c Sat Apr 7 04:22:46 2012 (r233975)
@@ -221,12 +221,12 @@ generic_nand_attach(device_t dev)
/* 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_params = malloc(sizeof(struct onfi_params),
- M_NAND, M_WAITOK | M_ZERO);
+ M_NAND, M_WAITOK | M_ZERO);
if (onfi_params == NULL)
return (ENXIO);
@@ -389,7 +389,7 @@ generic_read_page(device_t nand, uint32_
page_to_row(&chip->chip_geom, page, &row);
if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row,
- offset))
+ offset))
return (ENXIO);
DELAY(chip->t_r);
@@ -427,7 +427,7 @@ generic_read_oob(device_t nand, uint32_t
offset += chip->chip_geom.page_size;
if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row,
- offset))
+ offset))
return (ENXIO);
DELAY(chip->t_r);
@@ -994,7 +994,7 @@ generic_correct_ecc(device_t dev, void *
struct nand_chip *chip = device_get_softc(dev);
struct chip_geom *cg = &chip->chip_geom;
- return (NANDBUS_CORRECT_ECC(device_get_parent(dev), buf,
+ return (NANDBUS_CORRECT_ECC(device_get_parent(dev), buf,
cg->page_size, readecc, calcecc));
}
Modified: projects/nand/sys/dev/nand/nand_geom.c
==============================================================================
--- projects/nand/sys/dev/nand/nand_geom.c Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/sys/dev/nand/nand_geom.c Sat Apr 7 04:22:46 2012 (r233975)
@@ -35,20 +35,21 @@ __FBSDID("$FreeBSD$");
#include <sys/uio.h>
#include <sys/bio.h>
#include <geom/geom.h>
-#include <geom/geom_nand.h>
+#include <geom/geom_disk.h>
#include <dev/nand/nand.h>
#include <dev/nand/nandbus.h>
-#include <dev/nand/nand_cdev.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 gnand_ioctl_t nand_ioctl;
-static gnand_strategy_t nand_strategy;
-static gnand_strategy_t nand_strategy_raw;
+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)
@@ -94,7 +95,7 @@ nand_strategy(struct bio *bp)
{
struct nand_chip *chip;
- chip = (struct nand_chip *)bp->bio_nand->d_drv1;
+ chip = (struct nand_chip *)bp->bio_disk->d_drv1;
bp->bio_driver1 = BIO_NAND_STD;
@@ -102,7 +103,7 @@ nand_strategy(struct bio *bp)
(bp->bio_cmd & BIO_READ) == BIO_READ ? "READ" :
((bp->bio_cmd & BIO_WRITE) == BIO_WRITE ? "WRITE" :
((bp->bio_cmd & BIO_DELETE) == BIO_DELETE ? "DELETE" : "UNKNOWN")),
- chip->num, chip);
+ chip->num, chip);
mtx_lock(&chip->qlock);
bioq_insert_tail(&chip->bioq, bp);
@@ -115,7 +116,7 @@ nand_strategy_raw(struct bio *bp)
{
struct nand_chip *chip;
- chip = (struct nand_chip *)bp->bio_nand->d_drv1;
+ chip = (struct nand_chip *)bp->bio_disk->d_drv1;
/* Inform taskqueue that it's a raw access */
bp->bio_driver1 = BIO_NAND_RAW;
@@ -124,7 +125,7 @@ nand_strategy_raw(struct bio *bp)
(bp->bio_cmd & BIO_READ) == BIO_READ ? "READ" :
((bp->bio_cmd & BIO_WRITE) == BIO_WRITE ? "WRITE" :
((bp->bio_cmd & BIO_DELETE) == BIO_DELETE ? "DELETE" : "UNKNOWN")),
- chip->num, chip);
+ chip->num, chip);
mtx_lock(&chip->qlock);
bioq_insert_tail(&chip->bioq, bp);
@@ -150,7 +151,41 @@ nand_oob_access(struct nand_chip *chip,
}
static int
-nand_ioctl(struct gnand *disk, u_long cmd, void *data, int fflag,
+nand_getattr(struct bio *bp)
+{
+ struct nand_chip *chip;
+ struct chip_geom *cg;
+ device_t dev;
+
+ 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);
+
+ do {
+ if (g_handleattr_int(bp, "NAND::oobsize", cg->oob_size))
+ break;
+ else if (g_handleattr_int(bp, "NAND::pagesize", cg->page_size))
+ break;
+ else if (g_handleattr_int(bp, "NAND::blocksize",
+ cg->block_size))
+ break;
+ else if (g_handleattr(bp, "NAND::device", &(dev),
+ sizeof(device_t)))
+ break;
+
+ return (ERESTART);
+ } while (0);
+
+ return (EJUSTRETURN);
+}
+
+static int
+nand_ioctl(struct disk *ndisk, u_long cmd, void *data, int fflag,
struct thread *td)
{
struct nand_chip *chip;
@@ -161,14 +196,12 @@ nand_ioctl(struct gnand *disk, u_long cm
int ret = 0;
uint8_t status;
- chip = (struct nand_chip *)disk->d_drv1;
+ chip = (struct nand_chip *)ndisk->d_drv1;
nandbus = device_get_parent(chip->dev);
if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) {
raw_rw = (struct nand_raw_rw *)data;
buf = malloc(raw_rw->len, M_NAND, M_WAITOK);
- if (!buf)
- return (ENOMEM);
}
switch (cmd) {
case NAND_IO_ERASE:
@@ -197,7 +230,7 @@ nand_ioctl(struct gnand *disk, u_long cm
break;
case NAND_IO_RAW_PROG:
- copyin(oob_rw->data, buf, oob_rw->len);
+ copyin(raw_rw->data, buf, raw_rw->len);
ret = nand_prog_pages_raw(chip, raw_rw->off, buf,
raw_rw->len);
break;
@@ -260,18 +293,6 @@ nand_io_proc(void *arg, int pending)
} else
panic("Unknown access type in bio->bio_driver1\n");
- if ((bp->bio_cmd & BIO_READOOB) == BIO_READOOB) {
- err = nand_oob_access(chip, bp->bio_offset /
- chip->chip_geom.page_size, 0,
- bp->bio_bcount, bp->bio_data, 0);
- }
-
- if ((bp->bio_cmd & BIO_WRITEOOB) == BIO_WRITEOOB) {
- err = nand_oob_access(chip, bp->bio_offset /
- chip->chip_geom.page_size, 0,
- bp->bio_bcount, bp->bio_data, 1);
- }
-
if ((bp->bio_cmd & BIO_DELETE) == BIO_DELETE) {
nand_debug(NDBG_GEOM, "Delete on chip%d offset %lld "
"length %ld\n", chip->num, bp->bio_offset,
@@ -281,9 +302,6 @@ nand_io_proc(void *arg, int pending)
bp->bio_bcount);
}
- if (err == ECC_CORRECTABLE)
- bp->bio_flags |= BIO_ECC;
-
if (err == 0 || err == ECC_CORRECTABLE)
bp->bio_resid = 0;
else {
@@ -301,65 +319,57 @@ nand_io_proc(void *arg, int pending)
int
create_geom_disk(struct nand_chip *chip)
{
- struct gnand *disk, *rdisk;
- device_t dev;
-
- dev = device_get_parent(chip->dev);
- dev = device_get_parent(dev);
+ struct disk *ndisk, *rdisk;
/* Create the disk device */
- disk = gnand_alloc();
- disk->d_strategy = nand_strategy;
- disk->d_ioctl = nand_ioctl;
- disk->d_name = "gnand";
- disk->d_drv1 = chip;
- disk->d_dev = dev;
- disk->d_maxsize = chip->chip_geom.block_size;
- disk->d_sectorsize = chip->chip_geom.page_size;
- disk->d_mediasize = chip->chip_geom.chip_size;
- disk->d_pagesize = chip->chip_geom.page_size;
- disk->d_oobsize = chip->chip_geom.oob_size;
- disk->d_unit = chip->num +
+ 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)
- disk->d_mediasize -= (2 * chip->chip_geom.block_size);
+ ndisk->d_mediasize -= (2 * chip->chip_geom.block_size);
- disk->d_flags = DISKFLAG_CANDELETE;
+ ndisk->d_flags = DISKFLAG_CANDELETE;
- snprintf(disk->d_ident, sizeof(disk->d_ident),
+ snprintf(ndisk->d_ident, sizeof(ndisk->d_ident),
"nand: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id);
- gnand_create(disk);
+ disk_create(ndisk, DISK_VERSION);
/* Create the RAW disk device */
- rdisk = gnand_alloc();
+ 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_dev = dev;
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_pagesize = chip->chip_geom.page_size;
- rdisk->d_oobsize = chip->chip_geom.oob_size;
- rdisk->d_unit = chip->num +
+ rdisk->d_unit = chip->num +
10 * device_get_unit(device_get_parent(chip->dev));
rdisk->d_flags = DISKFLAG_CANDELETE;
- snprintf(rdisk->d_ident, sizeof(disk->d_ident),
+ snprintf(rdisk->d_ident, sizeof(rdisk->d_ident),
"nand_raw: Man:0x%02x Dev:0x%02x", chip->id.man_id,
chip->id.dev_id);
- gnand_create(rdisk);
+ disk_create(rdisk, DISK_VERSION);
- chip->disk = disk;
+ chip->ndisk = ndisk;
chip->rdisk = rdisk;
mtx_init(&chip->qlock, "NAND I/O lock", NULL, MTX_DEF);
@@ -370,8 +380,10 @@ create_geom_disk(struct nand_chip *chip)
taskqueue_thread_enqueue, &chip->tq);
taskqueue_start_threads(&chip->tq, 1, PI_DISK, "nand taskq");
- device_printf(chip->dev, "Created gnand%d for chip [0x%0x, 0x%0x]\n",
- disk->d_unit, chip->id.man_id, chip->id.dev_id);
+ 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);
}
@@ -382,8 +394,8 @@ destroy_geom_disk(struct nand_chip *chip
struct bio *bp;
taskqueue_free(chip->tq);
- gnand_destroy(chip->disk);
- gnand_destroy(chip->rdisk);
+ disk_destroy(chip->ndisk);
+ disk_destroy(chip->rdisk);
mtx_lock(&chip->qlock);
for (;;) {
Modified: projects/nand/sys/dev/nand/nandsim.c
==============================================================================
--- projects/nand/sys/dev/nand/nandsim.c Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/sys/dev/nand/nandsim.c Sat Apr 7 04:22:46 2012 (r233975)
@@ -70,9 +70,9 @@ static void nandsim_print_log(struct sim
static struct nandsim_chip *get_nandsim_chip(uint8_t, uint8_t);
static struct cdevsw nandsim_cdevsw = {
- .d_version = D_VERSION,
- .d_ioctl = nandsim_ioctl,
- .d_name = "nandsim",
+ .d_version = D_VERSION,
+ .d_ioctl = nandsim_ioctl,
+ .d_name = "nandsim",
};
int
@@ -263,7 +263,7 @@ nandsim_destroy_chip(struct sim_ctrl_chi
{
struct sim_ctrl_conf *ctrl_conf;
- nand_debug(NDBG_SIM,"destroy chip num:%d at ctrl:%d", chip->chip_num,
+ nand_debug(NDBG_SIM,"destroy chip num:%d at ctrl:%d", chip->chip_num,
chip->ctrl_num);
if (chip->ctrl_num >= MAX_SIM_DEV ||
@@ -657,7 +657,7 @@ nandsim_modevent(module_t mod __unused,
break;
default:
return (EOPNOTSUPP);
- }
+ }
return (0);
}
Modified: projects/nand/sys/dev/nand/nandsim_chip.c
==============================================================================
--- projects/nand/sys/dev/nand/nandsim_chip.c Sat Apr 7 04:00:30 2012 (r233974)
+++ projects/nand/sys/dev/nand/nandsim_chip.c Sat Apr 7 04:22:46 2012 (r233975)
@@ -470,8 +470,8 @@ nandchip_get_addr_byte(struct nandsim_ch
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),
+ 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) {
More information about the svn-src-projects
mailing list