/* * Copyright (c) 2022, Artinchip Technology Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ #include #include "usbh_core.h" #include "usbh_msc.h" #ifdef KERNEL_RTTHREAD #include struct rt_device udisk_dev; struct usbh_msc *active_msc_class; static rt_err_t rt_udisk_init(rt_device_t dev) { active_msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda"); if (active_msc_class == NULL) { printf("do not find /dev/sda\r\n"); return -1; } return RT_EOK; } static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { rt_err_t ret; ret = usbh_msc_scsi_read10(active_msc_class, pos, buffer, size); if (ret != RT_EOK) { rt_kprintf("usb mass_storage read failed\n"); return 0; } return size; } static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) { rt_err_t ret; ret = usbh_msc_scsi_write10(active_msc_class, pos, buffer, size); if (ret != RT_EOK) { rt_kprintf("usb mass_storage write %d sector failed\n", size); return 0; } return size; } static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args) { /* check parameter */ RT_ASSERT(dev != RT_NULL); if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) { struct rt_device_blk_geometry *geometry; geometry = (struct rt_device_blk_geometry *)args; if (geometry == RT_NULL) return -RT_ERROR; geometry->bytes_per_sector = active_msc_class->blocksize; geometry->block_size = 1 * active_msc_class->blocksize; geometry->sector_count = active_msc_class->blocknum; } return RT_EOK; } #ifdef RT_USING_DEVICE_OPS const static struct rt_device_ops udisk_device_ops = { rt_udisk_init, RT_NULL, RT_NULL, rt_udisk_read, rt_udisk_write, rt_udisk_control }; #endif void udisk_init(void) { udisk_dev.type = RT_Device_Class_Block; #ifdef RT_USING_DEVICE_OPS udisk_dev.ops = &udisk_device_ops; #else udisk_dev.init = rt_udisk_init; udisk_dev.read = rt_udisk_read; udisk_dev.write = rt_udisk_write; udisk_dev.control = rt_udisk_control; #endif udisk_dev.user_data = NULL; rt_device_register(&udisk_dev, "udisk", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); #ifdef RT_USING_DFS_MNTTABLE LOG_I("try to mount file system!"); /* try to mount file system on this block device */ dfs_mount_device(&udisk_dev); #else int ret = 0; ret = dfs_mount(udisk_dev.parent.name, "/", "elm", 0, 0); if (ret == 0) { printf("udisk mount successfully\n"); } else { printf("udisk mount failed, ret = %d\n", ret); } #endif } #endif int usbh_msc_connect_hook(void) { int ret = 0; struct usbh_msc * msc_class = NULL; msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda"); if (msc_class == NULL) { USB_LOG_RAW("do not find /dev/sda\r\n"); return -1; } /* Mount fatfs usb massstorage */ #ifdef KERNEL_RTTHREAD udisk_init(); #endif return ret; }