mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 05:55:46 +08:00
mmcsd: add multi partitions prototype implementation
Signed-off-by: wanggang26 <wanggang26@xiaomi.com>
This commit is contained in:
@@ -60,6 +60,12 @@
|
|||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct mmcsd_part_s
|
||||||
|
{
|
||||||
|
FAR struct mmcsd_state_s *priv;
|
||||||
|
uint32_t nblocks; /* Number of blocks */
|
||||||
|
};
|
||||||
|
|
||||||
/* This structure is contains the unique state of the MMC/SD block driver */
|
/* This structure is contains the unique state of the MMC/SD block driver */
|
||||||
|
|
||||||
struct mmcsd_state_s
|
struct mmcsd_state_s
|
||||||
@@ -68,6 +74,7 @@ struct mmcsd_state_s
|
|||||||
uint8_t crefs; /* Open references on the driver */
|
uint8_t crefs; /* Open references on the driver */
|
||||||
mutex_t lock; /* Assures mutually exclusive access to the slot */
|
mutex_t lock; /* Assures mutually exclusive access to the slot */
|
||||||
int minor; /* Device number */
|
int minor; /* Device number */
|
||||||
|
struct mmcsd_part_s part; /* Partition data */
|
||||||
|
|
||||||
/* Status flags */
|
/* Status flags */
|
||||||
|
|
||||||
@@ -96,7 +103,6 @@ struct mmcsd_state_s
|
|||||||
|
|
||||||
uint8_t blockshift; /* Log2 of blocksize */
|
uint8_t blockshift; /* Log2 of blocksize */
|
||||||
uint16_t blocksize; /* Read block length (== block size) */
|
uint16_t blocksize; /* Read block length (== block size) */
|
||||||
uint32_t nblocks; /* Number of blocks */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -334,6 +334,7 @@ static ssize_t mmcsd_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
{
|
{
|
||||||
FAR struct mmcsd_file_s *mmcsdfile = filep->f_priv;
|
FAR struct mmcsd_file_s *mmcsdfile = filep->f_priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
|
FAR struct mmcsd_part_s *part;
|
||||||
char path[32];
|
char path[32];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
@@ -345,7 +346,8 @@ static ssize_t mmcsd_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUGASSERT(filep->f_priv);
|
DEBUGASSERT(filep->f_priv);
|
||||||
ret = mmcsdfile->read(filep, buffer, buflen, inode->i_private);
|
part = inode->i_private;
|
||||||
|
ret = mmcsdfile->read(filep, buffer, buflen, part->priv);
|
||||||
close_blockdriver(inode);
|
close_blockdriver(inode);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
+34
-17
@@ -689,7 +689,7 @@ static void mmcsd_decode_csd(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
|||||||
|
|
||||||
priv->blockshift = 9;
|
priv->blockshift = 9;
|
||||||
priv->blocksize = 1 << 9;
|
priv->blocksize = 1 << 9;
|
||||||
priv->nblocks = (csize + 1) << (19 - priv->blockshift);
|
priv->part.nblocks = (csize + 1) << (19 - priv->blockshift);
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS_INFO
|
#ifdef CONFIG_DEBUG_FS_INFO
|
||||||
decoded.u.sdblock.csize = csize;
|
decoded.u.sdblock.csize = csize;
|
||||||
@@ -710,7 +710,7 @@ static void mmcsd_decode_csd(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
|||||||
((csd[2] >> 30) & 3);
|
((csd[2] >> 30) & 3);
|
||||||
uint8_t csizemult = (csd[2] >> 15) & 7;
|
uint8_t csizemult = (csd[2] >> 15) & 7;
|
||||||
|
|
||||||
priv->nblocks = ((uint32_t)csize + 1) *
|
priv->part.nblocks = ((uint32_t)csize + 1) *
|
||||||
(1 << (csizemult + 2));
|
(1 << (csizemult + 2));
|
||||||
priv->blockshift = readbllen;
|
priv->blockshift = readbllen;
|
||||||
priv->blocksize = (1 << readbllen);
|
priv->blocksize = (1 << readbllen);
|
||||||
@@ -725,7 +725,7 @@ static void mmcsd_decode_csd(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
|||||||
|
|
||||||
if (priv->blocksize > 512)
|
if (priv->blocksize > 512)
|
||||||
{
|
{
|
||||||
priv->nblocks <<= (priv->blockshift - 9);
|
priv->part.nblocks <<= (priv->blockshift - 9);
|
||||||
priv->blocksize = 512;
|
priv->blocksize = 512;
|
||||||
priv->blockshift = 9;
|
priv->blockshift = 9;
|
||||||
}
|
}
|
||||||
@@ -882,8 +882,8 @@ static void mmcsd_decode_csd(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
|
|||||||
decoded.fileformat, decoded.mmcecc, decoded.crc);
|
decoded.fileformat, decoded.mmcecc, decoded.crc);
|
||||||
|
|
||||||
finfo("Capacity: %luKb, Block size: %db, nblocks: %d wrprotect: %d\n",
|
finfo("Capacity: %luKb, Block size: %db, nblocks: %d wrprotect: %d\n",
|
||||||
(unsigned long)MMCSD_CAPACITY(priv->nblocks, priv->blockshift),
|
(unsigned long)MMCSD_CAPACITY(priv->part.nblocks, priv->blockshift),
|
||||||
priv->blocksize, priv->nblocks, priv->wrprotect);
|
priv->blocksize, priv->part.nblocks, priv->wrprotect);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2161,11 +2161,13 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
|
|||||||
static int mmcsd_open(FAR struct inode *inode)
|
static int mmcsd_open(FAR struct inode *inode)
|
||||||
{
|
{
|
||||||
FAR struct mmcsd_state_s *priv;
|
FAR struct mmcsd_state_s *priv;
|
||||||
|
FAR struct mmcsd_part_s *part;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
finfo("Entry\n");
|
finfo("Entry\n");
|
||||||
DEBUGASSERT(inode->i_private);
|
DEBUGASSERT(inode->i_private);
|
||||||
priv = inode->i_private;
|
part = inode->i_private;
|
||||||
|
priv = part->priv;
|
||||||
|
|
||||||
/* Just increment the reference count on the driver */
|
/* Just increment the reference count on the driver */
|
||||||
|
|
||||||
@@ -2192,11 +2194,13 @@ static int mmcsd_open(FAR struct inode *inode)
|
|||||||
static int mmcsd_close(FAR struct inode *inode)
|
static int mmcsd_close(FAR struct inode *inode)
|
||||||
{
|
{
|
||||||
FAR struct mmcsd_state_s *priv;
|
FAR struct mmcsd_state_s *priv;
|
||||||
|
FAR struct mmcsd_part_s *part;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
finfo("Entry\n");
|
finfo("Entry\n");
|
||||||
DEBUGASSERT(inode->i_private);
|
DEBUGASSERT(inode->i_private);
|
||||||
priv = inode->i_private;
|
part = inode->i_private;
|
||||||
|
priv = part->priv;
|
||||||
|
|
||||||
/* Decrement the reference count on the block driver */
|
/* Decrement the reference count on the block driver */
|
||||||
|
|
||||||
@@ -2225,13 +2229,16 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||||||
blkcnt_t startsector, unsigned int nsectors)
|
blkcnt_t startsector, unsigned int nsectors)
|
||||||
{
|
{
|
||||||
FAR struct mmcsd_state_s *priv;
|
FAR struct mmcsd_state_s *priv;
|
||||||
|
FAR struct mmcsd_part_s *part;
|
||||||
size_t sector;
|
size_t sector;
|
||||||
size_t endsector;
|
size_t endsector;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
ssize_t ret = nsectors;
|
ssize_t ret = nsectors;
|
||||||
|
|
||||||
DEBUGASSERT(inode->i_private);
|
DEBUGASSERT(inode->i_private);
|
||||||
priv = inode->i_private;
|
part = inode->i_private;
|
||||||
|
priv = part->priv;
|
||||||
|
|
||||||
finfo("startsector: %" PRIuOFF " nsectors: %u sectorsize: %d\n",
|
finfo("startsector: %" PRIuOFF " nsectors: %u sectorsize: %d\n",
|
||||||
startsector, nsectors, priv->blocksize);
|
startsector, nsectors, priv->blocksize);
|
||||||
|
|
||||||
@@ -2303,13 +2310,16 @@ static ssize_t mmcsd_write(FAR struct inode *inode,
|
|||||||
blkcnt_t startsector, unsigned int nsectors)
|
blkcnt_t startsector, unsigned int nsectors)
|
||||||
{
|
{
|
||||||
FAR struct mmcsd_state_s *priv;
|
FAR struct mmcsd_state_s *priv;
|
||||||
|
FAR struct mmcsd_part_s *part;
|
||||||
size_t sector;
|
size_t sector;
|
||||||
size_t endsector;
|
size_t endsector;
|
||||||
ssize_t nwrite;
|
ssize_t nwrite;
|
||||||
ssize_t ret = nsectors;
|
ssize_t ret = nsectors;
|
||||||
|
|
||||||
DEBUGASSERT(inode->i_private);
|
DEBUGASSERT(inode->i_private);
|
||||||
priv = inode->i_private;
|
part = inode->i_private;
|
||||||
|
priv = part->priv;
|
||||||
|
|
||||||
finfo("startsector: %" PRIuOFF " nsectors: %u sectorsize: %d\n",
|
finfo("startsector: %" PRIuOFF " nsectors: %u sectorsize: %d\n",
|
||||||
startsector, nsectors, priv->blocksize);
|
startsector, nsectors, priv->blocksize);
|
||||||
|
|
||||||
@@ -2377,6 +2387,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode,
|
|||||||
static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
||||||
{
|
{
|
||||||
FAR struct mmcsd_state_s *priv;
|
FAR struct mmcsd_state_s *priv;
|
||||||
|
FAR struct mmcsd_part_s *part;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
finfo("Entry\n");
|
finfo("Entry\n");
|
||||||
@@ -2388,7 +2399,9 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
|||||||
|
|
||||||
/* Is there a (supported) card inserted in the slot? */
|
/* Is there a (supported) card inserted in the slot? */
|
||||||
|
|
||||||
priv = inode->i_private;
|
part = inode->i_private;
|
||||||
|
priv = part->priv;
|
||||||
|
|
||||||
ret = mmcsd_lock(priv);
|
ret = mmcsd_lock(priv);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@@ -2409,7 +2422,7 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
|||||||
geometry->geo_available = true;
|
geometry->geo_available = true;
|
||||||
geometry->geo_mediachanged = priv->mediachanged;
|
geometry->geo_mediachanged = priv->mediachanged;
|
||||||
geometry->geo_writeenabled = !mmcsd_wrprotected(priv);
|
geometry->geo_writeenabled = !mmcsd_wrprotected(priv);
|
||||||
geometry->geo_nsectors = priv->nblocks;
|
geometry->geo_nsectors = part->nblocks;
|
||||||
geometry->geo_sectorsize = priv->blocksize;
|
geometry->geo_sectorsize = priv->blocksize;
|
||||||
|
|
||||||
finfo("available: true mediachanged: %s writeenabled: %s\n",
|
finfo("available: true mediachanged: %s writeenabled: %s\n",
|
||||||
@@ -2439,11 +2452,13 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
|||||||
static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
|
static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
FAR struct mmcsd_state_s *priv;
|
FAR struct mmcsd_state_s *priv;
|
||||||
|
FAR struct mmcsd_part_s *part;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
finfo("Entry\n");
|
finfo("Entry\n");
|
||||||
DEBUGASSERT(inode->i_private);
|
DEBUGASSERT(inode->i_private);
|
||||||
priv = inode->i_private;
|
part = inode->i_private;
|
||||||
|
priv = part->priv;
|
||||||
|
|
||||||
/* Process the IOCTL by command */
|
/* Process the IOCTL by command */
|
||||||
|
|
||||||
@@ -3042,11 +3057,11 @@ static int mmcsd_read_extcsd(FAR struct mmcsd_state_s *priv,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->nblocks = (extcsd[215] << 24) | (extcsd[214] << 16) |
|
priv->part.nblocks = (extcsd[215] << 24) | (extcsd[214] << 16) |
|
||||||
(extcsd[213] << 8) | extcsd[212];
|
(extcsd[213] << 8) | extcsd[212];
|
||||||
|
|
||||||
finfo("MMC ext CSD read succsesfully, number of block %" PRId32 "\n",
|
finfo("MMC ext CSD read succsesfully, number of block %" PRId32 "\n",
|
||||||
priv->nblocks);
|
priv->part.nblocks);
|
||||||
|
|
||||||
SDIO_GOTEXTCSD(priv->dev, extcsd);
|
SDIO_GOTEXTCSD(priv->dev, extcsd);
|
||||||
|
|
||||||
@@ -4071,7 +4086,8 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
|
|||||||
/* Yes... */
|
/* Yes... */
|
||||||
|
|
||||||
finfo("Capacity: %" PRIu32 " Kbytes\n",
|
finfo("Capacity: %" PRIu32 " Kbytes\n",
|
||||||
MMCSD_CAPACITY(priv->nblocks, priv->blockshift));
|
MMCSD_CAPACITY(priv->part.nblocks,
|
||||||
|
priv->blockshift));
|
||||||
priv->mediachanged = true;
|
priv->mediachanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4081,11 +4097,12 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
|
|||||||
|
|
||||||
/* Create a MMCSD device name */
|
/* Create a MMCSD device name */
|
||||||
|
|
||||||
|
priv->part.priv = priv;
|
||||||
snprintf(devname, sizeof(devname), "/dev/mmcsd%d", priv->minor);
|
snprintf(devname, sizeof(devname), "/dev/mmcsd%d", priv->minor);
|
||||||
|
|
||||||
/* Inode private data is a reference to the MMCSD state structure */
|
/* Inode private data is a reference to the MMCSD state structure */
|
||||||
|
|
||||||
register_blockdriver(devname, &g_bops, 0666, priv);
|
register_blockdriver(devname, &g_bops, 0666, &priv->part);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Regardless of whether or not a card was successfully initialized,
|
/* Regardless of whether or not a card was successfully initialized,
|
||||||
@@ -4366,7 +4383,7 @@ int mmcsd_slotinitialize(int minor, FAR struct sdio_dev_s *dev)
|
|||||||
snprintf(devname, sizeof(devname), "/dev/mmcsd%d", minor);
|
snprintf(devname, sizeof(devname), "/dev/mmcsd%d", minor);
|
||||||
|
|
||||||
finfo("MMC: %s %" PRIu64 "KB %s %s mode\n", devname,
|
finfo("MMC: %s %" PRIu64 "KB %s %s mode\n", devname,
|
||||||
((uint64_t)priv->nblocks << priv->blockshift) >> 10,
|
((uint64_t)priv->part.nblocks << priv->blockshift) >> 10,
|
||||||
priv->widebus ? "4-bits" : "1-bit",
|
priv->widebus ? "4-bits" : "1-bit",
|
||||||
mmc_get_mode_name(priv->mode));
|
mmc_get_mode_name(priv->mode));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user