drivers: disk: add DISK_IOCTL_CTRL_DEINIT command to supported IOCTLs
Add DISK_IOCTL_CTRL_DEINIT ioctl command to disk subsystem. When disk_access_ioctl() is called with this command, the disk will be de-initialized. After this IOCTL completes, the disk can safely be reinitialized. Fixes #60628 Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
parent
fb2d5c338b
commit
d18cbb60b2
10 changed files with 60 additions and 4 deletions
|
|
@ -435,6 +435,7 @@ static int disk_flash_access_ioctl(struct disk_info *disk, uint8_t cmd, void *bu
|
|||
ctx = CONTAINER_OF(disk, struct flashdisk_data, info);
|
||||
|
||||
switch (cmd) {
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
case DISK_IOCTL_CTRL_SYNC:
|
||||
k_mutex_lock(&ctx->lock, K_FOREVER);
|
||||
rc = flashdisk_cache_commit(ctx);
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ static int loopback_disk_access_ioctl(struct disk_info *disk, uint8_t cmd, void
|
|||
*(uint32_t *)buff = LOOPBACK_SECTOR_SIZE;
|
||||
return 0;
|
||||
}
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
case DISK_IOCTL_CTRL_SYNC:
|
||||
return fs_sync(&ctx->file);
|
||||
case DISK_IOCTL_CTRL_INIT:
|
||||
|
|
|
|||
|
|
@ -85,6 +85,13 @@ static int disk_mmc_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buf)
|
|||
switch (cmd) {
|
||||
case DISK_IOCTL_CTRL_INIT:
|
||||
return disk_mmc_access_init(disk);
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
mmc_ioctl(&data->card, DISK_IOCTL_CTRL_SYNC, NULL);
|
||||
/* sd_init() will toggle power to MMC, so we can just mark
|
||||
* disk as uninitialized
|
||||
*/
|
||||
data->status = SD_UNINIT;
|
||||
return 0;
|
||||
default:
|
||||
return mmc_ioctl(&data->card, cmd, buf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ static int nvme_disk_ioctl(struct disk_info *disk, uint8_t cmd, void *buff)
|
|||
*(uint32_t *)buff = nvme_namespace_get_sector_size(ns);
|
||||
|
||||
break;
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
case DISK_IOCTL_CTRL_SYNC:
|
||||
ret = nvme_disk_flush(ns);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ static int disk_ram_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff
|
|||
*(uint32_t *)buff = 1U;
|
||||
break;
|
||||
case DISK_IOCTL_CTRL_INIT:
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -307,14 +307,18 @@ static int stm32_sdmmc_access_init(struct disk_info *disk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_SDMMC_STM32_EMMC)
|
||||
static void stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv)
|
||||
static int stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv)
|
||||
{
|
||||
#if defined(CONFIG_SDMMC_STM32_EMMC)
|
||||
HAL_MMC_DeInit(&priv->hsd);
|
||||
#else
|
||||
HAL_SD_DeInit(&priv->hsd);
|
||||
|
||||
stm32_sdmmc_clock_disable(priv);
|
||||
}
|
||||
#endif
|
||||
priv->status = DISK_STATUS_UNINIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_sdmmc_access_status(struct disk_info *disk)
|
||||
{
|
||||
|
|
@ -483,6 +487,8 @@ static int stm32_sdmmc_access_ioctl(struct disk_info *disk, uint8_t cmd,
|
|||
break;
|
||||
case DISK_IOCTL_CTRL_INIT:
|
||||
return stm32_sdmmc_access_init(disk);
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
return stm32_sdmmc_access_deinit(priv);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,8 +89,16 @@ static int disk_sdmmc_access_ioctl(struct disk_info *disk, uint8_t cmd, void *bu
|
|||
const struct device *dev = disk->dev;
|
||||
struct sdmmc_data *data = dev->data;
|
||||
|
||||
switch (cmd) {
|
||||
case DISK_IOCTL_CTRL_INIT:
|
||||
return disk_sdmmc_access_init(disk);
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
sdmmc_ioctl(&data->card, DISK_IOCTL_CTRL_SYNC, NULL);
|
||||
/* sd_init() will toggle power to SDMMC, so we can just mark
|
||||
* disk as uninitialized
|
||||
*/
|
||||
data->status = SD_UNINIT;
|
||||
return 0;
|
||||
default:
|
||||
return sdmmc_ioctl(&data->card, cmd, buf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,18 @@ extern "C" {
|
|||
* device
|
||||
*/
|
||||
#define DISK_IOCTL_CTRL_INIT 6
|
||||
/** Deinitialize the disk. This IOCTL can be used to de-initialize the disk,
|
||||
* enabling it to be removed from the system if the disk is hot-pluggable.
|
||||
* Disk usage is reference counted, so for a given disk the
|
||||
* `DISK_IOCTL_CTRL_DEINIT` IOCTL must be issued as many times as the
|
||||
* `DISK_IOCTL_CTRL_INIT` IOCTL was issued in order to de-initialize it.
|
||||
*
|
||||
* This macro optionally accepts a pointer to a boolean as the `buf` parameter,
|
||||
* which if true indicates the disk should be forcibly stopped, ignoring all
|
||||
* reference counts. The disk driver must report success if a forced stop is
|
||||
* requested, but this operation is inherently unsafe.
|
||||
*/
|
||||
#define DISK_IOCTL_CTRL_DEINIT 7
|
||||
|
||||
/**
|
||||
* @brief Possible return bitmasks for disk_status()
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ extern "C" {
|
|||
* @ref disk_access_ioctl with the IOCTL @ref DISK_IOCTL_CTRL_INIT.
|
||||
*
|
||||
* Disk initialization is reference counted, so only the first successful call
|
||||
* to initialize a uninitialized disk will actually initialize the disk
|
||||
* to initialize a uninitialized (or previously de-initialized) disk will
|
||||
* actually initialize the disk
|
||||
*
|
||||
* @param[in] pdrv Disk name
|
||||
*
|
||||
|
|
|
|||
|
|
@ -139,6 +139,24 @@ int disk_access_ioctl(const char *pdrv, uint8_t cmd, void *buf)
|
|||
LOG_ERR("Disk reference count at max value");
|
||||
}
|
||||
break;
|
||||
case DISK_IOCTL_CTRL_DEINIT:
|
||||
if ((buf != NULL) && (*((bool *)buf))) {
|
||||
/* Force deinit disk */
|
||||
disk->refcnt = 0U;
|
||||
disk->ops->ioctl(disk, cmd, buf);
|
||||
rc = 0;
|
||||
} else if (disk->refcnt == 1U) {
|
||||
rc = disk->ops->ioctl(disk, cmd, buf);
|
||||
if (rc == 0) {
|
||||
disk->refcnt--;
|
||||
}
|
||||
} else if (disk->refcnt > 0) {
|
||||
disk->refcnt--;
|
||||
rc = 0;
|
||||
} else {
|
||||
LOG_WRN("Disk is already deinitialized");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = disk->ops->ioctl(disk, cmd, buf);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue