svn commit: r233073 - projects/nand/sys/geom
Grzegorz Bernacki
gjb at semihalf.com
Sat Mar 17 18:09:33 UTC 2012
W dniu 2012-03-17 09:56, Pawel Jakub Dawidek pisze:
> 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?
BIO_READOOB/BIO_WRITEOOB to read from areas of chip which are not
supposed to store
regular data. Our purpose is to have BIO_READ/BIO_WRITE to access data
on the chip and
BIO_READOOB/BIO_WRITEOOB to access metadata.
grzesiek
>
> 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) {
More information about the svn-src-projects
mailing list