db6e411b1e9cb0e4a6b6074c1b988d54bf883f44
[SCSI2SD-V6.git] / src / firmware / usb_device / usbd_msc_storage_sd.c
1 //      Copyright (C) 2016 Michael McMaster <michael@codesrc.com>
2 //
3 //      This file is part of SCSI2SD.
4 //
5 //      SCSI2SD is free software: you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation, either version 3 of the License, or
8 //      (at your option) any later version.
9 //
10 //      SCSI2SD is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
17
18
19 #include "usbd_msc_storage_sd.h"
20 #include "stm32f2xx.h"
21 #include "bsp_driver_sd.h"
22 #include "../bsp.h"
23 #include "../led.h"
24 #include "../sd.h"
25 #include "../config.h"
26 #include "../geometry.h"
27 #include "../inquiry.h"
28 #include "usb_device.h"
29
30
31
32 static int8_t s2s_usbd_storage_Init(uint8_t lun);
33
34 static int8_t s2s_usbd_storage_GetCapacity(
35         uint8_t lun,
36         uint32_t *block_num,
37         uint16_t *block_size);
38
39 static int8_t s2s_usbd_storage_IsReady(uint8_t lun);
40
41 static int8_t s2s_usbd_storage_IsWriteProtected(uint8_t lun);
42
43 int8_t s2s_usbd_storage_Read(
44         uint8_t lun,
45         uint8_t *buf,
46         uint32_t blk_addr,
47         uint16_t blk_len);
48
49 int8_t s2s_usbd_storage_Write(
50         uint8_t lun,
51         uint8_t *buf,
52         uint32_t blk_addr,
53         uint16_t blk_len);
54
55 int8_t s2s_usbd_storage_GetMaxLun (void);
56 uint32_t s2s_usbd_storage_Inquiry (uint8_t lun, uint8_t* buf, uint8_t maxlen);
57
58
59 USBD_StorageTypeDef USBD_MSC_SD_fops =
60 {
61         s2s_usbd_storage_Init,
62         s2s_usbd_storage_GetCapacity,
63         s2s_usbd_storage_IsReady,
64         s2s_usbd_storage_IsWriteProtected,
65         s2s_usbd_storage_Read,
66         s2s_usbd_storage_Write,
67         s2s_usbd_storage_GetMaxLun,
68         s2s_usbd_storage_Inquiry
69 };
70
71 static const S2S_TargetCfg* getUsbConfig(uint8_t lun) {
72         int count = 0;
73         for (int i = 0; i < S2S_MAX_TARGETS; ++i)
74         {
75                 const S2S_TargetCfg* cfg = s2s_getConfigByIndex(i);
76                 if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
77                 {
78                         if (count == lun)
79                         {
80                                 return cfg;
81                         }
82                         else
83                         {
84                                 count++;
85                         }
86                 }
87         }
88         return s2s_getConfigByIndex(0); // Fallback, try not to crash
89 }
90
91 int8_t s2s_usbd_storage_Init(uint8_t lun)
92 {
93         return (0);
94 }
95
96 int8_t s2s_usbd_storage_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
97 {
98         const S2S_TargetCfg* cfg = getUsbConfig(lun);
99
100         uint32_t capacity = getScsiCapacity(
101                 cfg->sdSectorStart,
102                 cfg->bytesPerSector,
103                 cfg->scsiSectors);
104
105         *block_num  = capacity;
106         *block_size = cfg->bytesPerSector;
107         return (0);
108 }
109
110 uint32_t s2s_usbd_storage_Inquiry (uint8_t lun, uint8_t* buf, uint8_t maxlen)
111 {
112         const S2S_TargetCfg* cfg = getUsbConfig(lun);
113
114         return s2s_getStandardInquiry(cfg, buf, maxlen);
115 }
116
117 int8_t  s2s_usbd_storage_IsReady (uint8_t lun)
118 {
119         return (0);
120 }
121
122
123 int8_t s2s_usbd_storage_IsWriteProtected (uint8_t lun)
124 {
125         return  0;
126 }
127
128 int8_t s2s_usbd_storage_Read (uint8_t lun,
129                 uint8_t *buf,
130                 uint32_t blk_addr,
131                 uint16_t blk_len)
132 {
133         s2s_ledOn();
134         const S2S_TargetCfg* cfg = getUsbConfig(lun);
135
136         if (cfg->bytesPerSector == 512)
137         {
138                 BSP_SD_ReadBlocks_DMA(
139                         (uint32_t*) buf,
140                         (cfg->sdSectorStart + blk_addr) * 512ll,
141                         512,
142                         blk_len);
143         }
144         else
145         {
146                 int sdPerScsi = SDSectorsPerSCSISector(cfg->bytesPerSector);
147                 int sdSectorNum =  cfg->sdSectorStart + (blk_addr * sdPerScsi);
148
149                 for (int blk = 0; blk < blk_len; ++blk)
150                 {
151                         for (int i = 0; i < SDSectorsPerSCSISector(cfg->bytesPerSector); ++i)
152                         {
153                                 uint8_t partial[512] S2S_DMA_ALIGN;
154                                 BSP_SD_ReadBlocks_DMA(
155                                         (uint32_t*) partial,
156                                         sdSectorNum * 512LL,
157                                         512,
158                                         1);
159                                 sdSectorNum++;
160
161                                 int validBytes = cfg->bytesPerSector % SD_SECTOR_SIZE;
162                                 if (validBytes == 0) validBytes = SD_SECTOR_SIZE;
163
164                                 memcpy(buf, partial, validBytes);
165
166                                 buf += validBytes;
167                         }
168
169                 }
170
171         }
172         s2s_ledOff();
173         return 0;
174 }
175
176 int8_t s2s_usbd_storage_Write (uint8_t lun,
177                 uint8_t *buf,
178                 uint32_t blk_addr,
179                 uint16_t blk_len)
180 {
181         s2s_ledOn();
182         const S2S_TargetCfg* cfg = getUsbConfig(lun);
183
184         if (cfg->bytesPerSector == 512)
185         {
186                 BSP_SD_WriteBlocks_DMA(
187                         (uint32_t*) buf,
188                         (cfg->sdSectorStart + blk_addr) * 512ll,
189                         512,
190                         blk_len);
191         }
192         else
193         {
194                 int sdPerScsi = SDSectorsPerSCSISector(cfg->bytesPerSector);
195                 int sdSectorNum =  cfg->sdSectorStart + (blk_addr * sdPerScsi);
196
197                 for (int blk = 0; blk < blk_len; ++blk)
198                 {
199                         for (int i = 0; i < SDSectorsPerSCSISector(cfg->bytesPerSector); ++i)
200                         {
201                                 uint8_t partial[512] S2S_DMA_ALIGN;
202                                 BSP_SD_WriteBlocks_DMA(
203                                         (uint32_t*) partial,
204                                         sdSectorNum * 512LL,
205                                         512,
206                                         1);
207                                 sdSectorNum++;
208
209                                 int validBytes = cfg->bytesPerSector % SD_SECTOR_SIZE;
210                                 if (validBytes == 0) validBytes = SD_SECTOR_SIZE;
211
212                                 memcpy(buf, partial, validBytes);
213
214                                 buf += validBytes;
215                         }
216
217                 }
218
219         }
220
221         s2s_ledOff();
222         return 0;
223 }
224
225 int8_t s2s_usbd_storage_GetMaxLun (void)
226 {
227         int count = 0;
228         for (int i = 0; i < S2S_MAX_TARGETS; ++i)
229         {
230                 const S2S_TargetCfg* cfg = s2s_getConfigByIndex(i);
231                 if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
232                 {
233                         count++;
234                 }
235         }
236         return count - 1 < 0 ? 0 : count - 1;
237 }
238
239 void s2s_initUsbDeviceStorage(void)
240 {
241         USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_MSC_SD_fops);
242 }
243