M4521_BSP V3.02.000
The Board Support Package for M4521
Umas_FATFS.c
Go to the documentation of this file.
1/**************************************************************************/
12#include <stdio.h>
13#include <string.h>
14
15#include "M4521.h"
16#include "usbh_core.h"
17
18#include "Umas.h"
19#include "diskio.h"
20#include "usbh_umas.h"
21
23
24UMAS_DATA_T *g_umas = NULL;
25static int g_disk_lun;
26static uint32_t g_sector_size, g_total_sector_num;
27
28
29
30static uint8_t usb_stor_sense_notready[18] =
31{
32 0x70/* current error */, 0, 0x02/* not ready */, 0, 0,
33 0x0a/* additional length */, 0, 0, 0, 0,
34 0x04/* not ready */, 0x03 /* manual intervention */
35};
36
37
38/* run command */
39static int run_scsi_command(SCSI_CMD_T *srb, UMAS_DATA_T *umas)
40{
41 /* reject the command if the direction indicator is UNKNOWN */
42 if(srb->sc_data_direction == SCSI_DATA_UNKNOWN)
43 {
44 UMAS_DEBUG("run_scsi_command - UNKNOWN data direction\n");
45 umas->srb.result = DID_ERROR << 16;
46 return -1;
47 }
48
49#if 0
50 /* reject if target != 0 or if LUN is higher than the maximum known LUN */
51 if(umas->srb.target && (!(umas->flags & UMAS_FL_SCM_MULT_TARG)))
52 {
53 UMAS_DEBUG("run_scsi_command - Bad target number (%d/%d)\n", umas->srb.target, umas->srb.lun);
54 umas->srb.result = DID_BAD_TARGET << 16;
55 return -1;
56 }
57#endif
58
59 if(umas->srb.lun > umas->max_lun)
60 {
61 UMAS_DEBUG("run_scsi_command - Bad LUN (%d/%d)\n", srb->target, srb->lun);
62 umas->srb.result = DID_BAD_TARGET << 16;
63 return -1;
64 }
65
66 /* handle those devices which can't do a START_STOP */
67 if((srb->cmnd[0] == START_STOP) && (umas->flags & UMAS_FL_START_STOP))
68 {
69 UMAS_DEBUG("run_scsi_command - Skipping START_STOP command\n");
70 umas->srb.result = GOOD << 1;
71 return -1;
72 }
73
74 /* our device has gone - pretend not ready */
75 if(!umas->pusb_dev)
76 {
77 UMAS_DEBUG("run_scsi_command - Request is for removed device\n");
78 /*
79 * For REQUEST_SENSE, it's the data. But for anything else,
80 * it should look like we auto-sensed for it.
81 */
82 if(umas->srb.cmnd[0] == REQUEST_SENSE)
83 {
84 memcpy(srb->request_buff,
85 usb_stor_sense_notready, sizeof(usb_stor_sense_notready));
86 srb->result = GOOD << 1;
87 }
88 else
89 {
90 memcpy(srb->sense_buffer,
91 usb_stor_sense_notready, sizeof(usb_stor_sense_notready));
92 srb->result = CHECK_CONDITION << 1;
93 }
94 }
95 else /* !umas->pusb_dev */
96 {
97#ifdef UMAS_VERBOSE_DEBUG
98 UMAS_DEBUG_ShowCommand(srb);
99#endif
100 /* we've got a command, let's do it! */
101 umas->proto_handler(srb, umas);
102 }
103
104 /* indicate that the command is done */
105 if(umas->srb.result != DID_ABORT << 16)
106 {
107 UMAS_VDEBUG("run_scsi_command - scsi cmd done, result=0x%x\n", srb->result);
108 }
109 else
110 {
111 UMAS_DEBUG("run_scsi_command - scsi command aborted\n");
112 }
113
114 return srb->result;
115}
116
117
118int test_unit_ready(UMAS_DATA_T *umas, int lun)
119{
120 SCSI_CMD_T *srb = &umas->srb;
121
122 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
123 srb->cmnd[0] = TEST_UNIT_READY;
124 srb->cmnd[1] = lun << 5;
125 srb->cmd_len = 6;
126 srb->request_bufflen = 0;
127 srb->use_sg = 0;
128 srb->sc_data_direction = SCSI_DATA_READ;
129 srb->sense_buffer[0] = 0;
130 srb->sense_buffer[2] = 0;
131 return run_scsi_command(srb, umas);
132}
133
134
135int request_sense(UMAS_DATA_T *umas, int lun)
136{
137 SCSI_CMD_T *srb = &umas->srb;
138
139 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
140 srb->cmnd[0] = REQUEST_SENSE;
141 srb->cmnd[1] = lun << 5;
142 srb->cmnd[4] = 18;
143 srb->cmd_len = 12;
144 srb->request_bufflen = 18;
145 srb->use_sg = 0;
146 srb->sc_data_direction = SCSI_DATA_READ;
147 return run_scsi_command(srb, umas);
148}
149
150
151int try_test_unit_ready(UMAS_DATA_T *umas)
152{
153 int retries;
154
155 for(retries = 0; retries < 10; retries++)
156 {
157 if(test_unit_ready(umas, 0) == 0)
158 return 0;
159 }
160 return -1;
161}
162
163
164/*===========================================================================
165 *
166 * USB Disk Driver
167 *
168 *==========================================================================*/
169
170int usbh_umas_disk_status(void)
171{
172 if(g_umas == NULL)
173 return STA_NODISK;
174 return 0;
175}
176
177
178DRESULT usbh_umas_ioctl(int cmd, void *buff)
179{
180 switch(cmd)
181 {
182 case CTRL_SYNC:
183 return RES_OK;
184
185 case GET_SECTOR_COUNT:
186 *(uint32_t *)buff = g_total_sector_num;
187 return RES_OK;
188
189 case GET_SECTOR_SIZE:
190 *(uint32_t *)buff = g_sector_size;
191 return RES_OK;
192
193 case GET_BLOCK_SIZE:
194 *(uint32_t *)buff = g_sector_size;
195 return RES_OK;
196
197 case CTRL_ERASE_SECTOR:
198 return RES_OK;
199 }
200 return RES_PARERR;
201}
202
203
204DRESULT usbh_umas_read(uint8_t *buff, uint32_t sector_no, int number_of_sector)
205{
206 SCSI_CMD_T *srb;
207 int retry = 10;
208
209 if(g_umas == NULL)
210 return RES_ERROR;
211
212 //UMAS_DEBUG("usbh_umas_read - buff=0x%x, sector=%d, count=%d\n", (int)buff, sector_no, number_of_sector);
213 if(sector_no >= g_total_sector_num)
214 {
215 UMAS_DEBUG("usbh_umas_read - exceed disk size! (%d/%d)\n", sector_no, g_total_sector_num);
216 return RES_ERROR;
217 }
218
219 srb = &g_umas->srb;
220
221do_retry:
222
223 srb->request_buff = (uint8_t *)buff;
224
225 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
226 srb->cmnd[0] = READ_10;
227 srb->cmnd[1] = g_disk_lun << 5;
228 srb->cmnd[2] = (sector_no >> 24) & 0xFF;
229 srb->cmnd[3] = (sector_no >> 16) & 0xFF;
230 srb->cmnd[4] = (sector_no >> 8) & 0xFF;
231 srb->cmnd[5] = sector_no & 0xFF;
232 srb->cmnd[7] = (number_of_sector >> 8) & 0xFF;
233 srb->cmnd[8] = number_of_sector & 0xFF;
234 srb->cmd_len = 10;
235
236 srb->request_bufflen = g_sector_size * number_of_sector;
237
238 srb->use_sg = 0;
239 srb->sc_data_direction = SCSI_DATA_READ;
240
241 if(run_scsi_command(srb, g_umas) != 0)
242 {
243 if(retry > 0)
244 {
245 retry--;
246 goto do_retry;
247 }
248
249 UMAS_DEBUG("usbh_umas_read - failed at sector %d (%d)\n", sector_no, number_of_sector);
250 return RES_ERROR;
251 }
252 return RES_OK;
253}
254
255
256
257DRESULT usbh_umas_write(uint8_t *buff, uint32_t sector_no, int number_of_sector)
258{
259 SCSI_CMD_T *srb;
260 int retry = 3;
261
262 if(g_umas == NULL)
263 return RES_ERROR;
264
265 if(sector_no >= g_total_sector_num)
266 {
267 UMAS_DEBUG("usbh_umas_write - exceed disk size! (%d/%d)\n", sector_no, g_total_sector_num);
268 return RES_ERROR;
269 }
270
271 srb = &g_umas->srb;
272
273do_retry:
274 //UMAS_DEBUG("usbh_umas_write - Write Sector: %d %d\n", sector_no, number_of_sector);
275 srb->request_buff = (uint8_t *)buff;
276
277 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
278 srb->cmnd[0] = WRITE_10;
279 srb->cmnd[1] = g_disk_lun << 5;
280 srb->cmnd[2] = (sector_no >> 24) & 0xFF;
281 srb->cmnd[3] = (sector_no >> 16) & 0xFF;
282 srb->cmnd[4] = (sector_no >> 8) & 0xFF;
283 srb->cmnd[5] = sector_no & 0xFF;
284 srb->cmnd[7] = (number_of_sector >> 8) & 0xFF;
285 srb->cmnd[8] = number_of_sector & 0xFF;
286 srb->cmd_len = 10;
287
288 srb->request_bufflen = g_sector_size * number_of_sector;
289
290 srb->use_sg = 0;
291 srb->sc_data_direction = SCSI_DATA_WRITE;
292
293 if(run_scsi_command(srb, g_umas) != 0)
294 {
295 if(retry > 0)
296 {
297 retry--;
298 goto do_retry;
299 }
300
301 UMAS_DEBUG("usbh_umas_write - failed at sector %d (%d)\n", sector_no, number_of_sector);
302 return RES_ERROR;
303 }
304 return RES_OK;
305}
306
307
308int UMAS_InitUmasDevice(UMAS_DATA_T *umas)
309{
310 int retries;
311 SCSI_CMD_T *srb = &umas->srb;
312 int8_t bHasMedia;
313 uint32_t stack_buff[256 / 4];
314
315 memset(srb, 0, sizeof(SCSI_CMD_T));
316 srb->request_buff = (void *)&stack_buff[0];
317 memset(srb->request_buff, 0, 256);
318
319 for(g_disk_lun = umas->max_lun; g_disk_lun >= 0; g_disk_lun--)
320 {
321 UMAS_DEBUG("\n\n\n******* Read lun %d ******\n\n", g_disk_lun);
322
323 UMAS_DEBUG("INQUIRY ==>\n");
324 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
325 srb->cmnd[0] = INQUIRY;
326 srb->cmnd[1] = g_disk_lun << 5;
327 srb->cmnd[4] = 36;
328 srb->cmd_len = 6;
329 srb->request_bufflen = 36;
330 srb->use_sg = 0;
331 srb->sc_data_direction = SCSI_DATA_READ;
332
333 if(run_scsi_command(srb, umas) != 0)
334 UMAS_DEBUG("INQUIRY - command failed!\n");
335
336 UMAS_DEBUG("TEST UNIT READY ==>\n");
337 bHasMedia = FALSE;
338 for(retries = 0; retries < 3; retries++)
339 {
340 if(test_unit_ready(umas, g_disk_lun) != 0)
341 {
342 //UMAS_DEBUG("TEST_UNIT_READY - command failed\n");
343 //break;
344 }
345 else if(srb->result == 0)
346 {
347 bHasMedia = TRUE;
348 break;
349 }
350
351 if((srb->result < 0) || (srb->sense_buffer[2] != UNIT_ATTENTION))
352 {
353 UMAS_DEBUG("TEST_UNIT_READY not UNIT_ATTENTION!\n");
354 //break;
355 }
356
357 /*
358 * If the drive has indicated to us that it doesn't have
359 * any media in it, don't bother with any of the rest of
360 * this crap.
361 */
362 if((srb->result < 0) &&
363 (srb->sense_buffer[2] == UNIT_ATTENTION) &&
364 (srb->sense_buffer[12] == 0x3A))
365 {
366 UMAS_DEBUG("TEST_UNIT_READY - no media\n");
367 //break;
368 }
369
370 /* Look for non-removable devices that return NOT_READY.
371 * Issue command to spin up drive for these cases. */
372 if((srb->result < 0) && (srb->sense_buffer[2] == NOT_READY))
373 {
374 UMAS_DEBUG("TEST_UNIT_READY - not ready, will retry.\n");
375 }
376 usbh_mdelay(100);
377 }
378
379 if(bHasMedia == FALSE)
380 continue;
381
382 UMAS_DEBUG("REQUEST SENSE ==>\n");
383
384 if(request_sense(umas, g_disk_lun) == 0)
385 {
386 //HexDumpBuffer("REQUEST_SENSE result", srb->request_buff, 256);
387 if((srb->request_buff[16] == 0) && (srb->request_buff[17] == 0))
388 UMAS_DEBUG("REQUEST_SENSE - no sense\n");
389 else
390 UMAS_DEBUG("REQUEST_SENSE - attention %02x %02x\n", srb->request_buff[16], srb->request_buff[17]);
391 }
392 else
393 UMAS_DEBUG("REQUEST_SENSE failed!\n");;
394
395 UMAS_DEBUG("READ CAPACITY ==>\n");
396 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
397 srb->cmnd[0] = READ_CAPACITY;
398 srb->cmnd[1] = g_disk_lun << 5;
399 srb->cmd_len = 9;
400 srb->sense_buffer[0] = 0;
401 srb->sense_buffer[2] = 0;
402 srb->sc_data_direction = SCSI_DATA_READ;
403 if(run_scsi_command(srb, umas) != 0)
404 {
405 UMAS_DEBUG("READ_CAPACITY failed!\n");
406 continue;
407 }
408
409 g_total_sector_num = (srb->request_buff[0] << 24) | (srb->request_buff[1] << 16) |
410 (srb->request_buff[2] << 8) | srb->request_buff[3];
411 g_sector_size = (srb->request_buff[4] << 24) | (srb->request_buff[5] << 16) |
412 (srb->request_buff[6] << 8) | srb->request_buff[7];
413
414 UMAS_DEBUG("USB disk found: size=%d MB, uTotalSectorN=%d\n", g_total_sector_num / 2048, g_total_sector_num);
415
416 ((mass_disk_t*)umas)->sector_size = g_sector_size;
417 ((mass_disk_t *)umas)->sector_number = g_total_sector_num;
418
419 break;
420 }
421
422 printf("g_disk_lun = %d\n", g_disk_lun);
423
424 g_umas = umas;
425
426 return 0;
427}
428
429#if 0
430// dummy
431void UMAS_ScanDeviceLun(UMAS_DATA_T *umas)
432{
433}
434#endif
435
437
438
463int32_t USBH_MassRawRead(mass_disk_t * disk, uint32_t sectorN, int32_t scnt, uint8_t *buff)
464{
465 UMAS_DATA_T *backup_umas;
466 int ret;
467
468 if(!disk)
469 return -1;
470
471 backup_umas = g_umas;
472 g_umas = (UMAS_DATA_T *)disk;
473 ret = usbh_umas_read(buff, sectorN, scnt);
474 g_umas = backup_umas;
475
476 if(ret == RES_OK)
477 return 0;
478 else
479 return -1;
480}
481
482
493int32_t USBH_MassRawWrite(mass_disk_t *disk, uint32_t sectorN, int32_t scnt, uint8_t *buff)
494{
495 UMAS_DATA_T *backup_umas;
496 int ret;
497
498 if(!disk)
499 return -1;
500
501 backup_umas = g_umas;
502 g_umas = (UMAS_DATA_T *)disk;
503 ret = usbh_umas_write(buff, sectorN, scnt);
504 g_umas = backup_umas;
505
506 if(ret == RES_OK)
507 return 0;
508 else
509 return -1;
510}
511
512 /* end of group USBH_MASS_EXPORTED_FUNCTIONS */
514 /* end of group USBH_MASS_Driver */
516 /* end of group USB_Host_Driver */
518
519
520
#define NULL
Definition: M4521.h:13912
#define TRUE
Definition: M4521.h:13905
#define FALSE
Definition: M4521.h:13908
int32_t USBH_MassRawRead(mass_disk_t *disk, uint32_t sectorN, int32_t scnt, uint8_t *buff)
Read raw data from connected USB Mass Storage disk.
Definition: Umas_FATFS.c:463
int32_t USBH_MassRawWrite(mass_disk_t *disk, uint32_t sectorN, int32_t scnt, uint8_t *buff)
Write raw data to connected USB Mass Storage disk.
Definition: Umas_FATFS.c:493
USB Host core driver header file.
void usbh_mdelay(uint32_t msec)
Definition: usbh_support.c:330
USB Host Mass Storage driver header file.