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