Date: Sat, 17 Mar 2012 03:23:13 +0000 (UTC) From: Grzegorz Bernacki <gber@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r233073 - projects/nand/sys/geom Message-ID: <201203170323.q2H3NDCs048073@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gber Date: Sat Mar 17 03:23:13 2012 New Revision: 233073 URL: http://svn.freebsd.org/changeset/base/233073 Log: Add changes required for proper working of NAND chip geom devices. Obtained from: Semihalf Supported by: FreeBSD Foundation, Juniper Networks Modified: projects/nand/sys/geom/geom.h projects/nand/sys/geom/geom_dev.c projects/nand/sys/geom/geom_disk.c projects/nand/sys/geom/geom_disk.h projects/nand/sys/geom/geom_io.c projects/nand/sys/geom/geom_slice.c Modified: projects/nand/sys/geom/geom.h ============================================================================== --- projects/nand/sys/geom/geom.h Sat Mar 17 03:18:28 2012 (r233072) +++ projects/nand/sys/geom/geom.h Sat Mar 17 03:23:13 2012 (r233073) @@ -309,6 +309,8 @@ struct bio *g_alloc_bio(void); void * g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error); int g_write_data(struct g_consumer *cp, off_t offset, void *ptr, off_t length); int g_delete_data(struct g_consumer *cp, off_t offset, off_t length); +void *g_read_oob(struct g_consumer *cp, off_t offset, off_t length, int *error); +int g_write_oob(struct g_consumer *cp, off_t offset, void *ptr, off_t length); void g_print_bio(struct bio *bp); /* geom_kern.c / geom_kernsim.c */ Modified: projects/nand/sys/geom/geom_dev.c ============================================================================== --- projects/nand/sys/geom/geom_dev.c Sat Mar 17 03:18:28 2012 (r233072) +++ projects/nand/sys/geom/geom_dev.c Sat Mar 17 03:23:13 2012 (r233073) @@ -311,8 +311,10 @@ g_dev_ioctl(struct cdev *dev, u_long cmd struct g_consumer *cp; struct g_provider *pp; struct g_kerneldump kd; + struct nand_oob_request *nand_req; off_t offset, length, chunk; int i, error; + void *buf; u_int u; gp = dev->si_drv1; @@ -345,6 +347,16 @@ g_dev_ioctl(struct cdev *dev, u_long cmd if (error == 0 && *(u_int *)data == 0) error = ENOENT; break; + case DIOCNOOBSIZE: + error = g_io_getattr("NAND::oobsize", cp, &i, data); + if (error == 0 && *(u_int *)data == 0) + error = ENOENT; + break; + case DIOCNBLKSIZE: + error = g_io_getattr("NAND::blocksize", cp, &i, data); + if (error == 0 && *(u_int *)data == 0) + error = ENOENT; + break; case DIOCGFRONTSTUFF: error = g_io_getattr("GEOM::frontstuff", cp, &i, data); break; @@ -396,6 +408,28 @@ g_dev_ioctl(struct cdev *dev, u_long cmd break; } break; + case DIOCNREADOOB: + nand_req = (struct nand_oob_request *)data; + + buf = g_read_oob(cp, nand_req->offset, nand_req->length, + &error); + if (error) + break; + + error = copyout(buf, nand_req->ubuf, nand_req->length); + break; + case DIOCNWRITEOOB: + nand_req = (struct nand_oob_request *)data; + + buf = g_malloc(nand_req->length, M_WAITOK); + error = copyin(nand_req->ubuf, buf, nand_req->length); + + if (error) + break; + + error = g_write_oob(cp, nand_req->offset, buf, + nand_req->length); + break; case DIOCGIDENT: error = g_io_getattr("GEOM::ident", cp, &i, data); break; Modified: projects/nand/sys/geom/geom_disk.c ============================================================================== --- projects/nand/sys/geom/geom_disk.c Sat Mar 17 03:18:28 2012 (r233072) +++ projects/nand/sys/geom/geom_disk.c Sat Mar 17 03:23:13 2012 (r233073) @@ -368,6 +368,10 @@ g_disk_start(struct bio *bp) break; else if (g_handleattr_int(bp, "GEOM::fwheads", dp->d_fwheads)) break; + else if (g_handleattr_int(bp, "NAND::oobsize", dp->n_oobsize)) + break; + else if (g_handleattr_int(bp, "NAND::pagesize", dp->n_pagesize)) + break; else if (g_handleattr_off_t(bp, "GEOM::frontstuff", 0)) break; else if (g_handleattr_str(bp, "GEOM::ident", dp->d_ident)) Modified: projects/nand/sys/geom/geom_disk.h ============================================================================== --- projects/nand/sys/geom/geom_disk.h Sat Mar 17 03:18:28 2012 (r233072) +++ projects/nand/sys/geom/geom_disk.h Sat Mar 17 03:23:13 2012 (r233073) @@ -86,6 +86,8 @@ struct disk { u_int d_maxsize; u_int d_stripeoffset; u_int d_stripesize; + u_int n_oobsize; + u_int n_pagesize; char d_ident[DISK_IDENT_SIZE]; char d_descr[DISK_IDENT_SIZE]; uint16_t d_hba_vendor; Modified: projects/nand/sys/geom/geom_io.c ============================================================================== --- projects/nand/sys/geom/geom_io.c Sat Mar 17 03:18:28 2012 (r233072) +++ projects/nand/sys/geom/geom_io.c Sat Mar 17 03:23:13 2012 (r233073) @@ -289,11 +289,13 @@ g_io_check(struct bio *bp) /* Fail if access counters dont allow the operation */ switch(bp->bio_cmd) { case BIO_READ: + case BIO_READOOB: case BIO_GETATTR: if (cp->acr == 0) return (EPERM); break; case BIO_WRITE: + case BIO_WRITEOOB: case BIO_DELETE: case BIO_FLUSH: if (cp->acw == 0) @@ -759,6 +761,52 @@ g_delete_data(struct g_consumer *cp, off return (error); } +void * +g_read_oob(struct g_consumer *cp, off_t offset, off_t length, int *error) +{ + struct bio *bp; + void *ptr; + int errorc; + + bp = g_alloc_bio(); + bp->bio_cmd = BIO_READOOB; + bp->bio_done = NULL; + bp->bio_offset = offset; + bp->bio_length = length; + ptr = g_malloc(length, M_WAITOK); + bp->bio_data = ptr; + g_io_request(bp, cp); + errorc = biowait(bp, "groob"); + if (error != NULL) + *error = errorc; + + g_destroy_bio(bp); + if (errorc) { + g_free(ptr); + ptr = NULL; + } + + return (ptr); +} + +int +g_write_oob(struct g_consumer *cp, off_t offset, void *ptr, off_t length) +{ + struct bio *bp; + int error; + + bp = g_alloc_bio(); + bp->bio_cmd = BIO_WRITEOOB; + bp->bio_done = NULL; + bp->bio_offset = offset; + bp->bio_length = length; + bp->bio_data = ptr; + g_io_request(bp, cp); + error = biowait(bp, "gwoob"); + g_destroy_bio(bp); + return (error); +} + void g_print_bio(struct bio *bp) { Modified: projects/nand/sys/geom/geom_slice.c ============================================================================== --- projects/nand/sys/geom/geom_slice.c Sat Mar 17 03:18:28 2012 (r233072) +++ projects/nand/sys/geom/geom_slice.c Sat Mar 17 03:23:13 2012 (r233073) @@ -215,7 +215,9 @@ g_slice_start(struct bio *bp) gsl = &gsp->slices[idx]; switch(bp->bio_cmd) { case BIO_READ: + case BIO_READOOB: case BIO_WRITE: + case BIO_WRITEOOB: case BIO_DELETE: if (bp->bio_offset > gsl->length) { g_io_deliver(bp, EINVAL); /* XXX: EWHAT ? */ @@ -233,8 +235,10 @@ g_slice_start(struct bio *bp) if (t + bp->bio_length <= ghp->offset) continue; switch(bp->bio_cmd) { - case BIO_READ: idx = ghp->ract; break; - case BIO_WRITE: idx = ghp->wact; break; + case BIO_READ: + case BIO_READOOB: idx = ghp->ract; break; + case BIO_WRITE: + case BIO_WRITEOOB: idx = ghp->wact; break; case BIO_DELETE: idx = ghp->dact; break; } switch(idx) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203170323.q2H3NDCs048073>