1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "diskio_impl.h"
8 #include "ffconf.h"
9 #include "ff.h"
10 #include "esp_log.h"
11 #include "diskio_usb.h"
12 #include "msc_scsi_bot.h"
13 #include "msc_common.h"
14 #include "usb/usb_types_stack.h"
15
16 static usb_disk_t *s_disks[FF_VOLUMES] = { NULL };
17
18 static const char *TAG = "diskio_usb";
19
usb_disk_initialize(BYTE pdrv)20 static DSTATUS usb_disk_initialize (BYTE pdrv)
21 {
22 return RES_OK;
23 }
24
usb_disk_status(BYTE pdrv)25 static DSTATUS usb_disk_status (BYTE pdrv)
26 {
27 return RES_OK;
28 }
29
usb_disk_read(BYTE pdrv,BYTE * buff,DWORD sector,UINT count)30 static DRESULT usb_disk_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
31 {
32 assert(pdrv < FF_VOLUMES);
33 assert(s_disks[pdrv]);
34
35 esp_err_t err;
36 usb_disk_t *disk = s_disks[pdrv];
37 size_t sector_size = disk->block_size;
38 msc_device_t *dev = __containerof(disk, msc_device_t, disk);
39
40 for (int i = 0; i < count; i++) {
41 err = scsi_cmd_read10(dev, &buff[i * sector_size], sector + i, 1, sector_size);
42 if (err != ESP_OK) {
43 ESP_LOGE(TAG, "scsi_cmd_read10 failed (%d)", err);
44 return RES_ERROR;
45 }
46
47 }
48
49 return RES_OK;
50 }
51
usb_disk_write(BYTE pdrv,const BYTE * buff,DWORD sector,UINT count)52 static DRESULT usb_disk_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
53 {
54 assert(pdrv < FF_VOLUMES);
55 assert(s_disks[pdrv]);
56
57 esp_err_t err;
58 usb_disk_t *disk = s_disks[pdrv];
59 size_t sector_size = disk->block_size;
60 msc_device_t *dev = __containerof(disk, msc_device_t, disk);
61
62 for (int i = 0; i < count; i++) {
63 err = scsi_cmd_write10(dev, &buff[i * sector_size], sector + i, 1, sector_size);
64 if (err != ESP_OK) {
65 ESP_LOGE(TAG, "scsi_cmd_write10 failed (%d)", err);
66 return RES_ERROR;
67 }
68
69 }
70 return RES_OK;
71 }
72
usb_disk_ioctl(BYTE pdrv,BYTE cmd,void * buff)73 static DRESULT usb_disk_ioctl (BYTE pdrv, BYTE cmd, void *buff)
74 {
75 assert(pdrv < FF_VOLUMES);
76 assert(s_disks[pdrv]);
77
78 usb_disk_t *disk = s_disks[pdrv];
79
80 switch (cmd) {
81 case CTRL_SYNC:
82 return RES_OK;
83 case GET_SECTOR_COUNT:
84 *((DWORD *) buff) = disk->block_count;
85 return RES_OK;
86 case GET_SECTOR_SIZE:
87 *((WORD *) buff) = disk->block_size;
88 return RES_OK;
89 case GET_BLOCK_SIZE:
90 return RES_ERROR;
91 }
92 return RES_ERROR;
93 }
94
ff_diskio_register_msc(BYTE pdrv,usb_disk_t * disk)95 void ff_diskio_register_msc(BYTE pdrv, usb_disk_t *disk)
96 {
97 assert(pdrv < FF_VOLUMES);
98
99 static const ff_diskio_impl_t usb_disk_impl = {
100 .init = &usb_disk_initialize,
101 .status = &usb_disk_status,
102 .read = &usb_disk_read,
103 .write = &usb_disk_write,
104 .ioctl = &usb_disk_ioctl
105 };
106 s_disks[pdrv] = disk;
107 ff_diskio_register(pdrv, &usb_disk_impl);
108 }
109
ff_diskio_get_pdrv_disk(const usb_disk_t * disk)110 BYTE ff_diskio_get_pdrv_disk(const usb_disk_t *disk)
111 {
112 for (int i = 0; i < FF_VOLUMES; i++) {
113 if (disk == s_disks[i]) {
114 return i;
115 }
116 }
117 return 0xff;
118 }
119