diff --git a/components/drivers/block/blk.c b/components/drivers/block/blk.c index a0c18acca9e..13b944d3308 100644 --- a/components/drivers/block/blk.c +++ b/components/drivers/block/blk.c @@ -109,19 +109,28 @@ static rt_err_t blk_control(rt_device_t dev, int cmd, void *args) { rt_err_t err; struct rt_blk_disk *disk = to_blk_disk(dev); + struct rt_device_blk_geometry disk_geometry; switch (cmd) { case RT_DEVICE_CTRL_BLK_GETGEOME: - if (args) - { - err = disk->ops->getgeome(disk, args); - } - else + if (!args) { err = -RT_EINVAL; + break; } + err = disk->ops->getgeome(disk, &disk_geometry); + if (err != RT_EOK) + { + break; + } +#ifdef RT_USING_LWP + err = blk_copy_to_user(args, &disk_geometry, sizeof(disk_geometry)); +#else + rt_memcpy(args, &disk_geometry, sizeof(disk_geometry)); + err = RT_EOK; +#endif break; case RT_DEVICE_CTRL_BLK_SYNC: @@ -187,13 +196,51 @@ static rt_err_t blk_control(rt_device_t dev, int cmd, void *args) break; case RT_DEVICE_CTRL_BLK_SSIZEGET: - device_get_blk_ssize(dev, args); - err = RT_EOK; + if (!args) + { + err = -RT_EINVAL; + break; + } + + err = disk->ops->getgeome(disk, &disk_geometry); + if (err != RT_EOK) + { + break; + } + + { + rt_uint32_t ksize = disk_geometry.bytes_per_sector; +#ifdef RT_USING_LWP + err = blk_copy_to_user(args, &ksize, sizeof(ksize)); +#else + rt_memcpy(args, &ksize, sizeof(ksize)); + err = RT_EOK; +#endif + } break; case RT_DEVICE_CTRL_ALL_BLK_SSIZEGET: - device_get_all_blk_ssize(dev, args); - err = RT_EOK; + if (!args) + { + err = -RT_EINVAL; + break; + } + + err = disk->ops->getgeome(disk, &disk_geometry); + if (err != RT_EOK) + { + break; + } + + { + rt_uint64_t ktotal = (rt_uint64_t)disk_geometry.bytes_per_sector * disk_geometry.sector_count; +#ifdef RT_USING_LWP + err = blk_copy_to_user(args, &ktotal, sizeof(ktotal)); +#else + rt_memcpy(args, &ktotal, sizeof(ktotal)); + err = RT_EOK; +#endif + } break; default: diff --git a/components/drivers/block/blk_dev.c b/components/drivers/block/blk_dev.c index 5c45aa5ecc3..163b2f7a880 100644 --- a/components/drivers/block/blk_dev.c +++ b/components/drivers/block/blk_dev.c @@ -68,25 +68,35 @@ static rt_err_t blk_dev_control(rt_device_t dev, int cmd, void *args) rt_err_t err = -RT_EINVAL; struct rt_blk_device *blk = to_blk(dev); struct rt_blk_disk *disk = blk->disk; - struct rt_device_blk_geometry disk_geometry, *geometry; + struct rt_device_blk_geometry disk_geometry; switch (cmd) { case RT_DEVICE_CTRL_BLK_GETGEOME: - if ((geometry = args)) + if (!args) { - if (!(err = disk->ops->getgeome(disk, &disk_geometry))) - { - geometry->bytes_per_sector = disk_geometry.bytes_per_sector; - geometry->block_size = disk_geometry.block_size; - geometry->sector_count = blk->sector_count; - } + err = -RT_EINVAL; + break; } - else + + if ((err = disk->ops->getgeome(disk, &disk_geometry)) != RT_EOK) { - err = -RT_EINVAL; + break; } + { + struct rt_device_blk_geometry kgeo; + kgeo.bytes_per_sector = disk_geometry.bytes_per_sector; + kgeo.block_size = disk_geometry.block_size; + kgeo.sector_count = blk->sector_count; + +#ifdef RT_USING_LWP + err = blk_copy_to_user(args, &kgeo, sizeof(kgeo)); +#else + rt_memcpy(args, &kgeo, sizeof(kgeo)); + err = RT_EOK; +#endif + } break; case RT_DEVICE_CTRL_BLK_SYNC: @@ -106,25 +116,68 @@ static rt_err_t blk_dev_control(rt_device_t dev, int cmd, void *args) break; case RT_DEVICE_CTRL_BLK_PARTITION: - if (args) + if (!args) { - rt_memcpy(args, &blk->partition, sizeof(blk->partition)); + err = -RT_EINVAL; + break; } - else +#ifdef RT_USING_LWP { - err = -RT_EINVAL; + struct dfs_partition kpart; + rt_memcpy(&kpart, &blk->partition, sizeof(kpart)); + kpart.lock = RT_NULL; + err = blk_copy_to_user(args, &kpart, sizeof(kpart)); } - +#else + rt_memcpy(args, &blk->partition, sizeof(blk->partition)); + err = RT_EOK; +#endif break; case RT_DEVICE_CTRL_BLK_SSIZEGET: - device_get_blk_ssize(dev, args); - err = RT_EOK; + if (!args) + { + err = -RT_EINVAL; + break; + } + + if ((err = disk->ops->getgeome(disk, &disk_geometry)) != RT_EOK) + { + break; + } + + { + rt_uint32_t ksize = disk_geometry.bytes_per_sector; +#ifdef RT_USING_LWP + err = blk_copy_to_user(args, &ksize, sizeof(ksize)); +#else + rt_memcpy(args, &ksize, sizeof(ksize)); + err = RT_EOK; +#endif + } break; case RT_DEVICE_CTRL_ALL_BLK_SSIZEGET: - device_get_all_blk_ssize(dev, args); - err = RT_EOK; + if (!args) + { + err = -RT_EINVAL; + break; + } + + if ((err = disk->ops->getgeome(disk, &disk_geometry)) != RT_EOK) + { + break; + } + + { + rt_uint64_t ktotal = (rt_uint64_t)disk_geometry.bytes_per_sector * blk->sector_count; +#ifdef RT_USING_LWP + err = blk_copy_to_user(args, &ktotal, sizeof(ktotal)); +#else + rt_memcpy(args, &ktotal, sizeof(ktotal)); + err = RT_EOK; +#endif + } break; default: diff --git a/components/drivers/block/blk_dev.h b/components/drivers/block/blk_dev.h index b433f57f876..c4f193ffed2 100644 --- a/components/drivers/block/blk_dev.h +++ b/components/drivers/block/blk_dev.h @@ -46,4 +46,29 @@ rt_err_t disk_remove_blk_dev(struct rt_blk_device *blk, rt_bool_t lockless); rt_uint32_t blk_request_ioprio(void); +#ifdef RT_USING_LWP +#include + +static inline rt_err_t blk_copy_to_user(void *dst, const void *src, size_t n) +{ + if (lwp_self() == RT_NULL) + { + rt_memcpy(dst, src, n); + return RT_EOK; + } + + if (!lwp_user_accessable(dst, n)) + { + return -RT_EFAULT; + } + + if (lwp_put_to_user(dst, (void *)src, n) == 0) + { + return -RT_EFAULT; + } + + return RT_EOK; +} +#endif + #endif /* __BLK_DEV_H__ */ diff --git a/components/drivers/block/blk_dfs.c b/components/drivers/block/blk_dfs.c index ce637b687c3..bb417860840 100644 --- a/components/drivers/block/blk_dfs.c +++ b/components/drivers/block/blk_dfs.c @@ -10,6 +10,7 @@ #include +#include "blk_dev.h" #include "blk_dfs.h" #include @@ -26,16 +27,28 @@ static int blk_fops_open(struct dfs_file *file) { struct rt_device *dev = file->vnode->data; struct blk_fops_data *data = rt_malloc(sizeof(*data)); + rt_err_t err; if (!data) { return (int)-RT_ENOMEM; } - dev->user_data = data; - rt_device_control(dev, RT_DEVICE_CTRL_BLK_GETGEOME, &data->geometry); - rt_device_control(dev, RT_DEVICE_CTRL_ALL_BLK_SSIZEGET, &file->vnode->size); + err = rt_device_control(dev, RT_DEVICE_CTRL_BLK_GETGEOME, &data->geometry); + if (err != RT_EOK) + { + rt_free(data); + return (int)err; + } + + err = rt_device_control(dev, RT_DEVICE_CTRL_ALL_BLK_SSIZEGET, &file->vnode->size); + if (err != RT_EOK) + { + rt_free(data); + return (int)err; + } + dev->user_data = data; return 0; } @@ -255,27 +268,3 @@ void device_set_blk_fops(struct rt_device *dev) { } #endif /* RT_USING_POSIX_DEVIO && RT_USING_DFS_V2 */ - -void device_get_blk_ssize(struct rt_device *dev, void *args) -{ - rt_uint32_t bytes_per_sector; - struct rt_device_blk_geometry geometry; - - rt_device_control(dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - bytes_per_sector = geometry.bytes_per_sector; - - RT_ASSERT(sizeof(bytes_per_sector) == sizeof(geometry.bytes_per_sector)); - - rt_memcpy(args, &bytes_per_sector, sizeof(bytes_per_sector)); -} - -void device_get_all_blk_ssize(struct rt_device *dev, void *args) -{ - rt_uint64_t count_mul_per; - struct rt_device_blk_geometry geometry; - - rt_device_control(dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - count_mul_per = geometry.bytes_per_sector * geometry.sector_count; - - rt_memcpy(args, &count_mul_per, sizeof(count_mul_per)); -} diff --git a/components/drivers/block/blk_dfs.h b/components/drivers/block/blk_dfs.h index c532869fc7d..58eeea89ffe 100644 --- a/components/drivers/block/blk_dfs.h +++ b/components/drivers/block/blk_dfs.h @@ -17,7 +17,5 @@ #define RT_DEVICE_CTRL_ALL_BLK_SSIZEGET 0x80081272 /**< get number of bytes per sector * sector counts */ void device_set_blk_fops(struct rt_device *dev); -void device_get_blk_ssize(struct rt_device *dev, void *args); -void device_get_all_blk_ssize(struct rt_device *dev, void *args); #endif /* __BLK_DFS_H__ */