disk_access: reference count initialization calls for disks

Reference count initialization calls for disks. This changes the
behavior of the disk_access_init() function, such that disks will no
longer be initialized again if the first disk access init call
succeeds.

Disk access is reference counted in preparation for supporting disk
de-initialization, where a balanced number of disk de-initialization
calls with disk initialization calls will de-initialize the disk.

Also, remove code in disk drivers that was already checking against
duplicate disk_access_init() calls.

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
Daniel DeGrasse 2024-05-31 19:16:52 +00:00 committed by Fabio Baltieri
parent 3c41820d06
commit 3386a43a51
6 changed files with 22 additions and 17 deletions

View file

@ -38,11 +38,6 @@ static int disk_mmc_access_init(struct disk_info *disk)
struct mmc_data *data = dev->data;
int ret;
if (data->status == SD_OK) {
/* Called twice, don't reinit */
return 0;
}
ret = sd_init(cfg->host_controller, &data->card);
if (ret) {
data->status = SD_ERROR;

View file

@ -265,10 +265,6 @@ static int stm32_sdmmc_access_init(struct disk_info *disk)
struct stm32_sdmmc_priv *priv = dev->data;
int err;
if (priv->status == DISK_STATUS_OK) {
return 0;
}
if (priv->status == DISK_STATUS_NOMEDIA) {
return -ENODEV;
}

View file

@ -37,11 +37,6 @@ static int disk_sdmmc_access_init(struct disk_info *disk)
struct sdmmc_data *data = dev->data;
int ret;
if (data->status == SD_OK) {
/* Called twice, don't reinit */
return 0;
}
if (!sd_is_card_present(cfg->host_controller)) {
return DISK_STATUS_NOMEDIA;
}

View file

@ -77,6 +77,8 @@ struct disk_info {
const struct disk_operations *ops;
/** Device associated to this disk */
const struct device *dev;
/** Internally used disk reference count */
uint16_t refcnt;
};
/**

View file

@ -41,6 +41,9 @@ extern "C" {
* This call is made by the consumer before doing any IO calls so that the
* disk or the backing device can do any initialization.
*
* Disk initialization is reference counted, so only the first successful call
* to initialize a uninitialized disk will actually initialize the disk
*
* @param[in] pdrv Disk name
*
* @return 0 on success, negative errno code on fail

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 Intel Corporation.
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -58,9 +59,19 @@ int disk_access_init(const char *pdrv)
struct disk_info *disk = disk_access_get_di(pdrv);
int rc = -EINVAL;
if ((disk != NULL) && (disk->ops != NULL) &&
(disk->ops->init != NULL)) {
rc = disk->ops->init(disk);
if ((disk != NULL) && (disk->refcnt == 0U)) {
/* Disk has not been initialized, start it */
if ((disk->ops != NULL) && (disk->ops->init != NULL)) {
rc = disk->ops->init(disk);
if (rc == 0) {
/* Increment reference count */
disk->refcnt++;
}
}
} else if ((disk != NULL) && (disk->refcnt < UINT16_MAX)) {
/* Disk reference count is nonzero, simply increment it */
disk->refcnt++;
rc = 0;
}
return rc;
@ -137,6 +148,9 @@ int disk_access_register(struct disk_info *disk)
goto reg_err;
}
/* Initialize reference count to zero */
disk->refcnt = 0U;
/* append to the disk list */
sys_dlist_append(&disk_access_list, &disk->node);
LOG_DBG("disk interface(%s) registered", disk->name);