diff --git a/components/drivers/block/blk_dev.c b/components/drivers/block/blk_dev.c index 5c45aa5ecc3..2e70c633ae4 100644 --- a/components/drivers/block/blk_dev.c +++ b/components/drivers/block/blk_dev.c @@ -19,6 +19,31 @@ #include #endif +#ifdef RT_USING_LWP +#include + +static 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 + static rt_err_t blk_dev_open(rt_device_t dev, rt_uint16_t oflag) { struct rt_blk_device *blk = to_blk(dev); @@ -68,25 +93,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 +141,69 @@ 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 + { + 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: + if(!args) { err = -RT_EINVAL; + break; } - break; + if((err = disk->ops->getgeome(disk, &disk_geometry)) != RT_EOK) + { + break; + } - case RT_DEVICE_CTRL_BLK_SSIZEGET: - device_get_blk_ssize(dev, args); - err = RT_EOK; + { + 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 + * 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_dfs.c b/components/drivers/block/blk_dfs.c index ce637b687c3..230b3886f01 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 @@ -33,9 +34,22 @@ static int blk_fops_open(struct dfs_file *file) } 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); + struct rt_blk_device *blk = to_blk(dev); + struct rt_blk_disk *disk = blk->disk; + struct rt_device_blk_geometry disk_geometry; + rt_err_t err = disk->ops->getgeome(disk, &disk_geometry); + if (err != RT_EOK) + { + rt_free(data); + return (int)err; + } + + data->geometry.bytes_per_sector = disk_geometry.bytes_per_sector; + data->geometry.block_size = disk_geometry.block_size; + data->geometry.sector_count = blk->sector_count; + + file->vnode->size = (off_t)disk_geometry.sector_count * disk_geometry.bytes_per_sector; return 0; }