From owner-svn-src-projects@FreeBSD.ORG Sat Apr 7 04:22:47 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CEE931065672; Sat, 7 Apr 2012 04:22:47 +0000 (UTC) (envelope-from gber@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7DBAF8FC08; Sat, 7 Apr 2012 04:22:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q374Mlcc041925; Sat, 7 Apr 2012 04:22:47 GMT (envelope-from gber@svn.freebsd.org) Received: (from gber@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q374Ml3s041915; Sat, 7 Apr 2012 04:22:47 GMT (envelope-from gber@svn.freebsd.org) Message-Id: <201204070422.q374Ml3s041915@svn.freebsd.org> From: Grzegorz Bernacki Date: Sat, 7 Apr 2012 04:22:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233975 - in projects/nand: include sys/dev/nand X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Apr 2012 04:22:48 -0000 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 #include -#include +#include 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#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 +#include + +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 #include #include -#include +#include #include #include -#include +#include #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) {