driver/mtd: get mtd_geometry_s.model for mtd partition and optimize code
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
a2be27ef7d
commit
ed6fb11de6
@ -73,10 +73,8 @@ struct mtd_partition_s
|
||||
* entire FLASH */
|
||||
off_t firstblock; /* Offset to the first block of the managed
|
||||
* sub-region */
|
||||
off_t neraseblocks; /* The number of erase blocks in the managed
|
||||
* sub-region */
|
||||
off_t blocksize; /* The size of one read/write block */
|
||||
uint16_t blkpererase; /* Number of R/W blocks in one erase block */
|
||||
struct mtd_geometry_s geo; /* The geometry for the partition */
|
||||
|
||||
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_PROCFS_EXCLUDE_PARTITIONS)
|
||||
struct mtd_partition_s *pnext; /* Pointer to next partition struct */
|
||||
@ -181,7 +179,7 @@ static bool part_blockcheck(FAR struct mtd_partition_s *priv, off_t block)
|
||||
{
|
||||
off_t partsize;
|
||||
|
||||
partsize = priv->neraseblocks * priv->blkpererase;
|
||||
partsize = priv->geo.neraseblocks * priv->blkpererase;
|
||||
return block < partsize;
|
||||
}
|
||||
|
||||
@ -195,12 +193,10 @@ static bool part_blockcheck(FAR struct mtd_partition_s *priv, off_t block)
|
||||
|
||||
static bool part_bytecheck(FAR struct mtd_partition_s *priv, off_t byoff)
|
||||
{
|
||||
off_t erasesize;
|
||||
off_t readend;
|
||||
|
||||
erasesize = priv->blocksize * priv->blkpererase;
|
||||
readend = (byoff + erasesize - 1) / erasesize;
|
||||
return readend <= priv->neraseblocks;
|
||||
readend = (byoff + priv->geo.erasesize - 1) / priv->geo.erasesize;
|
||||
return readend <= priv->geo.neraseblocks;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -337,7 +333,7 @@ static ssize_t part_read(FAR struct mtd_dev_s *dev, off_t offset,
|
||||
* underlying MTD driver perform the read.
|
||||
*/
|
||||
|
||||
newoffset = offset + priv->firstblock * priv->blocksize;
|
||||
newoffset = offset + priv->firstblock * priv->geo.blocksize;
|
||||
return priv->parent->read(priv->parent, newoffset, nbytes, buffer);
|
||||
}
|
||||
|
||||
@ -377,7 +373,7 @@ static ssize_t part_write(FAR struct mtd_dev_s *dev, off_t offset,
|
||||
* underlying MTD driver perform the write.
|
||||
*/
|
||||
|
||||
newoffset = offset + priv->firstblock * priv->blocksize;
|
||||
newoffset = offset + priv->firstblock * priv->geo.blocksize;
|
||||
return priv->parent->write(priv->parent, newoffset, nbytes, buffer);
|
||||
}
|
||||
|
||||
@ -403,19 +399,11 @@ static int part_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
|
||||
case MTDIOC_GEOMETRY:
|
||||
{
|
||||
FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)arg;
|
||||
if (geo)
|
||||
if (geo != NULL)
|
||||
{
|
||||
memset(geo, 0, sizeof(*geo));
|
||||
|
||||
/* Populate the geometry structure with information needed to
|
||||
* know the capacity and how to access the device.
|
||||
*/
|
||||
|
||||
geo->blocksize = priv->blocksize;
|
||||
geo->erasesize = priv->blocksize * priv->blkpererase;
|
||||
geo->neraseblocks = priv->neraseblocks;
|
||||
memcpy(geo, &priv->geo, sizeof(*geo));
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -425,8 +413,8 @@ static int part_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
|
||||
(FAR struct partition_info_s *)arg;
|
||||
if (info != NULL)
|
||||
{
|
||||
info->numsectors = priv->neraseblocks * priv->blkpererase;
|
||||
info->sectorsize = priv->blocksize;
|
||||
info->numsectors = priv->geo.neraseblocks * priv->blkpererase;
|
||||
info->sectorsize = priv->geo.blocksize;
|
||||
info->startsector = priv->firstblock;
|
||||
|
||||
strlcpy(info->parent, priv->parent->name,
|
||||
@ -455,7 +443,7 @@ static int part_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
|
||||
*/
|
||||
|
||||
*ppv = (FAR void *)(uintptr_t)
|
||||
(base + priv->firstblock * priv->blocksize);
|
||||
(base + priv->firstblock * priv->geo.blocksize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -467,7 +455,7 @@ static int part_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
|
||||
|
||||
ret = priv->parent->erase(priv->parent,
|
||||
priv->firstblock / priv->blkpererase,
|
||||
priv->neraseblocks);
|
||||
priv->geo.neraseblocks);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -709,12 +697,12 @@ static ssize_t part_procfs_read(FAR struct file *filep, FAR char *buffer,
|
||||
"%s%7ju %7ju %s\n",
|
||||
partname,
|
||||
(uintmax_t)attr->nextpart->firstblock / blkpererase,
|
||||
(uintmax_t)attr->nextpart->neraseblocks,
|
||||
(uintmax_t)attr->nextpart->geo.neraseblocks,
|
||||
attr->nextpart->parent->name);
|
||||
#else
|
||||
ret = snprintf(&buffer[total], buflen - total, "%7ju %7ju %s\n",
|
||||
(uintmax_t)attr->nextpart->firstblock / blkpererase,
|
||||
(uintmax_t)attr->nextpart->neraseblocks,
|
||||
(uintmax_t)attr->nextpart->geo.neraseblocks,
|
||||
attr->nextpart->parent->name);
|
||||
#endif
|
||||
|
||||
@ -846,53 +834,12 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd,
|
||||
off_t nblocks)
|
||||
{
|
||||
FAR struct mtd_partition_s *part;
|
||||
FAR struct mtd_geometry_s geo;
|
||||
unsigned int blkpererase;
|
||||
off_t erasestart;
|
||||
off_t eraseend;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(mtd);
|
||||
|
||||
/* Get the geometry of the FLASH device */
|
||||
|
||||
ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo));
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: mtd->ioctl failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the number of blocks per erase. There must be an even number of
|
||||
* blocks in one erase blocks.
|
||||
*/
|
||||
|
||||
blkpererase = geo.erasesize / geo.blocksize;
|
||||
DEBUGASSERT(blkpererase * geo.blocksize == geo.erasesize);
|
||||
|
||||
/* Adjust the offset and size if necessary so that they are multiples of
|
||||
* the erase block size (making sure that we do not go outside of the
|
||||
* requested sub-region). NOTE that 'eraseend' is the first erase block
|
||||
* beyond the sub-region.
|
||||
*/
|
||||
|
||||
erasestart = (firstblock + blkpererase - 1) / blkpererase;
|
||||
eraseend = (firstblock + nblocks) / blkpererase;
|
||||
|
||||
if (erasestart >= eraseend)
|
||||
{
|
||||
ferr("ERROR: sub-region too small\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Verify that the sub-region is valid for this geometry */
|
||||
|
||||
if (eraseend > geo.neraseblocks)
|
||||
{
|
||||
ferr("ERROR: sub-region too big\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate a partition device structure */
|
||||
|
||||
part = (FAR struct mtd_partition_s *)
|
||||
@ -903,6 +850,50 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the geometry of the FLASH device */
|
||||
|
||||
ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY,
|
||||
(unsigned long)((uintptr_t)&part->geo));
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: mtd->ioctl failed: %d\n", ret);
|
||||
kmm_free(part);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the number of blocks per erase. There must be an even number of
|
||||
* blocks in one erase blocks.
|
||||
*/
|
||||
|
||||
part->blkpererase = part->geo.erasesize / part->geo.blocksize;
|
||||
DEBUGASSERT(part->blkpererase * part->geo.blocksize ==
|
||||
part->geo.erasesize);
|
||||
|
||||
/* Adjust the offset and size if necessary so that they are multiples of
|
||||
* the erase block size (making sure that we do not go outside of the
|
||||
* requested sub-region). NOTE that 'eraseend' is the first erase block
|
||||
* beyond the sub-region.
|
||||
*/
|
||||
|
||||
erasestart = (firstblock + part->blkpererase - 1) / part->blkpererase;
|
||||
eraseend = (firstblock + nblocks) / part->blkpererase;
|
||||
|
||||
if (erasestart >= eraseend)
|
||||
{
|
||||
ferr("ERROR: sub-region too small\n");
|
||||
kmm_free(part);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Verify that the sub-region is valid for this geometry */
|
||||
|
||||
if (eraseend > part->geo.neraseblocks)
|
||||
{
|
||||
ferr("ERROR: sub-region too big\n");
|
||||
kmm_free(part);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the partition device structure. (unsupported methods were
|
||||
* nullified by kmm_zalloc).
|
||||
*/
|
||||
@ -920,10 +911,8 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd,
|
||||
part->child.name = "part";
|
||||
|
||||
part->parent = mtd;
|
||||
part->firstblock = erasestart * blkpererase;
|
||||
part->neraseblocks = eraseend - erasestart;
|
||||
part->blocksize = geo.blocksize;
|
||||
part->blkpererase = blkpererase;
|
||||
part->firstblock = erasestart * part->blkpererase;
|
||||
part->geo.neraseblocks = eraseend - erasestart;
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITION_NAMES
|
||||
strlcpy(part->name, "(noname)", sizeof(part->name));
|
||||
|
Loading…
Reference in New Issue
Block a user