svn commit: r233073 - projects/nand/sys/geom
Pawel Jakub Dawidek
pjd at FreeBSD.org
Sat Mar 17 08:57:36 UTC 2012
On Sat, Mar 17, 2012 at 03:23:13AM +0000, Grzegorz Bernacki wrote:
> 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.
Hmm, adding two new BIO types is a big deal. Is there an ongoing
discussion somewhere about this that I'm not aware of?
What's the difference between BIO_READOOB/BIO_WRITEOOB and
BIO_READ/BIO_WRITE exactly?
Also, instead of adding nand-specific ioctls why not to create dedicated
GEOM NAND class and use class ioctl method to implement those?
> 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) {
--
Pawel Jakub Dawidek http://www.wheelsystems.com
FreeBSD committer http://www.FreeBSD.org
Am I Evil? Yes, I Am! http://tupytaj.pl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/svn-src-projects/attachments/20120317/538f219f/attachment.pgp
More information about the svn-src-projects
mailing list