fs/partition: Try MTDIOC_GEOMETRY IOCTL before bops's geometry

fs/driver/fs_blockpartition.c:  Support MTD IOCTL
This commit is contained in:
Xiang Xiao 2018-11-08 09:41:54 -06:00 committed by Gregory Nutt
parent e27b6c46ec
commit d32d9d4b24
3 changed files with 56 additions and 19 deletions

View File

@ -45,6 +45,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/kmalloc.h>
#include "driver/driver.h"
@ -234,16 +235,33 @@ static int part_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
if (parent->u.i_bops->ioctl)
{
ret = parent->u.i_bops->ioctl(parent, cmd, arg);
if (ret >= 0 && cmd == BIOC_XIPBASE)
if (cmd == MTDIOC_PROTECT || cmd == MTDIOC_UNPROTECT)
{
FAR void **base = (FAR void **)arg;
struct geometry geo;
FAR struct mtd_protect_s *prot = (FAR struct mtd_protect_s *)arg;
ret = parent->u.i_bops->geometry(parent, &geo);
if (ret >= 0)
prot->startblock += dev->firstsector;
}
ret = parent->u.i_bops->ioctl(parent, cmd, arg);
if (ret >= 0)
{
if (cmd == BIOC_XIPBASE || cmd == MTDIOC_XIPBASE)
{
*base += dev->firstsector * geo.geo_sectorsize;
FAR void **base = (FAR void **)arg;
struct geometry geo;
ret = parent->u.i_bops->geometry(parent, &geo);
if (ret >= 0)
{
*base += dev->firstsector * geo.geo_sectorsize;
}
}
else if (cmd == MTDIOC_GEOMETRY)
{
FAR struct mtd_geometry_s *mgeo = (FAR struct mtd_geometry_s *)arg;
uint32_t blkper = mgeo->erasesize / mgeo->blocksize;
mgeo->neraseblocks = dev->nsectors / blkper;
}
}
}

View File

@ -143,6 +143,7 @@ int parse_block_partition(FAR const char *path,
FAR void *arg)
{
struct partition_state_s state;
struct mtd_geometry_s mgeo;
struct geometry geo;
int ret;
@ -152,16 +153,30 @@ int parse_block_partition(FAR const char *path,
return ret;
}
ret = state.blk->u.i_bops->geometry(state.blk, &geo);
state.mtd = NULL;
ret = state.blk->u.i_bops->ioctl(state.blk, MTDIOC_GEOMETRY, (unsigned long)&mgeo);
if (ret >= 0)
{
state.mtd = NULL;
state.blocksize = geo.geo_sectorsize;
state.erasesize = geo.geo_sectorsize;
state.nblocks = geo.geo_nsectors;
state.blocksize = mgeo.blocksize;
state.erasesize = mgeo.erasesize;
state.nblocks = mgeo.neraseblocks;
state.nblocks *= mgeo.erasesize / mgeo.blocksize;
ret = parse_partition(&state, handler, arg);
}
else
{
ret = state.blk->u.i_bops->geometry(state.blk, &geo);
if (ret >= 0)
{
state.blocksize = geo.geo_sectorsize;
state.erasesize = geo.geo_sectorsize;
state.nblocks = geo.geo_nsectors;
ret = parse_partition(&state, handler, arg);
}
}
close_blockdriver(state.blk);
return ret;
@ -188,10 +203,10 @@ int parse_mtd_partition(FAR struct mtd_dev_s *mtd,
FAR void *arg)
{
struct partition_state_s state;
struct mtd_geometry_s geo;
struct mtd_geometry_s mgeo;
int ret;
ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)&geo);
ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)&mgeo);
if (ret < 0)
{
return ret;
@ -199,11 +214,10 @@ int parse_mtd_partition(FAR struct mtd_dev_s *mtd,
state.blk = NULL;
state.mtd = mtd;
state.blocksize = geo.blocksize;
state.erasesize = geo.erasesize;
state.nblocks = geo.neraseblocks;
state.nblocks *= geo.erasesize / geo.blocksize;
state.blocksize = mgeo.blocksize;
state.erasesize = mgeo.erasesize;
state.nblocks = mgeo.neraseblocks;
state.nblocks *= mgeo.erasesize / mgeo.blocksize;
return parse_partition(&state, handler, arg);
}

View File

@ -4,6 +4,11 @@
* Copyright (C) 2018 Pinecone Inc. All rights reserved.
* Author: Xiang Xiao <xiaoxiang@pinecone.net>
*
* Derives from code originally written by:
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met: