27static volatile uint8_t g_fat_drv_used[USBDRV_CNT];
28static TCHAR _path[3] = {
'3',
':', 0 };
30static void fatfs_drive_int()
32 memset((uint8_t *)g_fat_drv_used, 0,
sizeof(g_fat_drv_used));
35static int fatfs_drive_alloc()
39 for(i = 0; i < USBDRV_CNT; i++)
41 if(g_fat_drv_used[i] == 0)
43 g_fat_drv_used[i] = 1;
47 msc_debug_msg(
"Memory out! No free FATFS USB drive slots!\n");
51static void fatfs_drive_free(
int drv_no)
53 _path[0] = drv_no +
'0';
54 f_mount(
NULL, _path, 1);
55 g_fat_drv_used[drv_no - USBDRV_0] = 0;
58static MSC_T * find_msc_by_drive(
int drv_no)
60 MSC_T *msc = g_msc_list;
64 if(msc->drv_no == drv_no)
71static void msc_list_add(MSC_T *msc)
73 if(g_msc_list ==
NULL)
80 msc->next = g_msc_list;
85static void msc_list_remove(MSC_T *msc)
91 g_msc_list = msc->next;
96 while((p->next != msc) && (p->next !=
NULL))
109static void get_max_lun(MSC_T *msc)
111 UDEV_T *udev = msc->iface->udev;
121 ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
122 0xFE, 0, 0, 1, buff, &read_len, 200);
125 msc_debug_msg(
"Get Max Lun command failed! Assign 0...\n");
128 usbh_clear_halt(udev, 0);
131 msc->max_lun = buff[0];
132 msc_debug_msg(
"Max lun is %d\n", msc->max_lun);
135void msc_reset(MSC_T *msc)
137 UDEV_T *udev = msc->iface->udev;
141 msc_debug_msg(
"Reset MSC device...\n");
143 ret = usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
144 0xFF, 0, msc->iface->if_num, 0,
NULL, &read_len, 100);
147 msc_debug_msg(
"UAMSS reset request failed!\n");
149 usbh_clear_halt(udev, msc->ep_bulk_out->bEndpointAddress);
150 usbh_clear_halt(udev, msc->ep_bulk_in->bEndpointAddress);
153static int msc_inquiry(MSC_T *msc)
155 struct bulk_cb_wrap *cmd_blk = &msc->cmd_blk;
158 msc_debug_msg(
"INQUIRY...\n");
159 memset(cmd_blk, 0,
sizeof(*cmd_blk));
161 cmd_blk->Flags = 0x80;
163 cmd_blk->CDB[0] = INQUIRY;
164 cmd_blk->CDB[1] = msc->lun << 5;
165 cmd_blk->CDB[4] = 36;
170 msc_debug_msg(
"INQUIRY command failed. [%d]\n", ret);
175 msc_debug_msg(
"INQUIRY command success.\n");
180static int msc_request_sense(MSC_T *msc)
182 struct bulk_cb_wrap *cmd_blk = &msc->cmd_blk;
185 msc_debug_msg(
"REQUEST_SENSE...\n");
186 memset(cmd_blk, 0,
sizeof(*cmd_blk));
188 cmd_blk->Flags = 0x80;
190 cmd_blk->CDB[0] = REQUEST_SENSE;
191 cmd_blk->CDB[1] = msc->lun << 5;
192 cmd_blk->CDB[4] = 18;
197 msc_debug_msg(
"REQUEST_SENSE command failed.\n");
204 msc_debug_msg(
"REQUEST_SENSE command success.\n");
205 if(msc->scsi_buff[2] != 0x6)
207 msc_debug_msg(
"Device is still not attention. 0x%x\n", msc->scsi_buff[2]);
214static int msc_test_unit_ready(MSC_T *msc)
216 struct bulk_cb_wrap *cmd_blk = &msc->cmd_blk;
219 msc_debug_msg(
"TEST_UNIT_READY...\n");
220 memset(cmd_blk, 0,
sizeof(*cmd_blk));
222 cmd_blk->Flags = 0x80;
224 cmd_blk->CDB[0] = TEST_UNIT_READY;
225 cmd_blk->CDB[1] = msc->lun << 5;
236 msc_debug_msg(
"TEST_UNIT_READY command success.\n");
253int usbh_umas_read(
int drv_no, uint32_t sec_no,
int sec_cnt, uint8_t *buff)
256 struct bulk_cb_wrap *cmd_blk;
261 msc = find_msc_by_drive(drv_no);
265 cmd_blk = &msc->cmd_blk;
268 memset(cmd_blk, 0,
sizeof(*cmd_blk));
270 cmd_blk->Flags = 0x80;
271 cmd_blk->Length = 10;
272 cmd_blk->CDB[0] = READ_10;
273 cmd_blk->CDB[1] = msc->lun << 5;
274 cmd_blk->CDB[2] = (sec_no >> 24) & 0xFF;
275 cmd_blk->CDB[3] = (sec_no >> 16) & 0xFF;
276 cmd_blk->CDB[4] = (sec_no >> 8) & 0xFF;
277 cmd_blk->CDB[5] = sec_no & 0xFF;
278 cmd_blk->CDB[7] = (sec_cnt >> 8) & 0xFF;
279 cmd_blk->CDB[8] = sec_cnt & 0xFF;
284 msc_debug_msg(
"usbh_umas_read failed! [%d]\n", ret);
302int usbh_umas_write(
int drv_no, uint32_t sec_no,
int sec_cnt, uint8_t *buff)
305 struct bulk_cb_wrap *cmd_blk;
310 msc = find_msc_by_drive(drv_no);
314 cmd_blk = &msc->cmd_blk;
315 memset((uint8_t *) & (msc->cmd_blk), 0,
sizeof(msc->cmd_blk));
318 cmd_blk->Length = 10;
319 cmd_blk->CDB[0] = WRITE_10;
320 cmd_blk->CDB[1] = msc->lun << 5;
321 cmd_blk->CDB[2] = (sec_no >> 24) & 0xFF;
322 cmd_blk->CDB[3] = (sec_no >> 16) & 0xFF;
323 cmd_blk->CDB[4] = (sec_no >> 8) & 0xFF;
324 cmd_blk->CDB[5] = sec_no & 0xFF;
325 cmd_blk->CDB[7] = (sec_cnt >> 8) & 0xFF;
326 cmd_blk->CDB[8] = sec_cnt & 0xFF;
331 msc_debug_msg(
"usbh_umas_write failed!\n");
352 msc = find_msc_by_drive(drv_no);
361 case GET_SECTOR_COUNT:
362 *(uint32_t *)buff = msc->uTotalSectorN;
365 case GET_SECTOR_SIZE:
366 *(uint32_t *)buff = msc->nSectorSize;
370 *(uint32_t *)buff = msc->nSectorSize;
387 if(find_msc_by_drive(drv_no) ==
NULL)
398int usbh_umas_reset_disk(
int drv_no)
403 msc_debug_msg(
"usbh_umas_reset_disk ...\n");
405 msc = find_msc_by_drive(drv_no);
409 udev = msc->iface->udev;
411 usbh_reset_device(udev);
416static int umass_init_device(MSC_T *msc)
418 MSC_T *try_msc = msc;
419 struct bulk_cb_wrap *cmd_blk;
421 int8_t bHasMedia = 0;
424 for(lun = 0; lun <= msc->max_lun; lun++)
426 msc_debug_msg(
"\n******* Read lun %d ******\n\n", lun);
429 cmd_blk = &try_msc->cmd_blk;
431 for(retries = 0; retries < 3; retries++)
439 if(msc_test_unit_ready(try_msc) == 0)
442 if(msc_request_sense(try_msc) == 0)
456 for(retries = 0; retries < 3; retries++)
458 msc_debug_msg(
"READ CAPACITY ==>\n");
460 memset(cmd_blk, 0,
sizeof(*cmd_blk));
462 cmd_blk->Flags = 0x80;
463 cmd_blk->Length = 10;
464 cmd_blk->CDB[0] = READ_CAPACITY;
465 cmd_blk->CDB[1] = lun << 5;
470 msc_debug_msg(
"READ_CAPACITY failed!\n");
482 try_msc->uTotalSectorN = (try_msc->scsi_buff[0] << 24) | (try_msc->scsi_buff[1] << 16) |
483 (try_msc->scsi_buff[2] << 8) | try_msc->scsi_buff[3];
484 try_msc->nSectorSize = (try_msc->scsi_buff[4] << 24) | (try_msc->scsi_buff[5] << 16) |
485 (try_msc->scsi_buff[6] << 8) | try_msc->scsi_buff[7];
487 try_msc->drv_no = fatfs_drive_alloc();
488 if(try_msc->drv_no < 0)
494 msc_debug_msg(
"USB disk [%c] found: size=%d MB, uTotalSectorN=%d\n", msc->drv_no +
'0', try_msc->uTotalSectorN / 2048, try_msc->uTotalSectorN);
496 msc_list_add(try_msc);
498 _path[0] = try_msc->drv_no +
'0';
499 f_mount(&try_msc->fatfs_vol, _path, 1);
506 try_msc = usbh_alloc_mem(
sizeof(*try_msc));
512 memcpy(try_msc, msc,
sizeof(*msc));
518 usbh_free_mem(try_msc,
sizeof(*try_msc));
524static int msc_probe(IFACE_T *iface)
526 ALT_IFACE_T *aif = iface->aif;
534 if(ifd->bInterfaceClass != USB_CLASS_MASS_STORAGE)
538 if((ifd->bInterfaceSubClass != MSC_SCLASS_SCSI) && (ifd->bInterfaceSubClass != MSC_SCLASS_8070) &&
539 (ifd->bInterfaceSubClass != MSC_SCLASS_RBC))
543 if(ifd->bInterfaceProtocol != MSC_SPROTO_BULK)
545 msc_debug_msg(
"Not bulk-only MSC device!\n");
549 msc = usbh_alloc_mem(
sizeof(*msc));
555 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
557 if((aif->ep[i].bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_BULK)
559 if((aif->ep[i].bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN)
560 msc->ep_bulk_in = &aif->ep[i];
562 msc->ep_bulk_out = &aif->ep[i];
566 if((msc->ep_bulk_in ==
NULL) || (msc->ep_bulk_out ==
NULL))
568 usbh_free_mem(msc,
sizeof(*msc));
574 msc_debug_msg(
"USB Mass Storage device found. Iface:%d, Alt Iface:%d, bep_in:0x%x, bep_out:0x%x\n", ifd->bInterfaceNumber, ifd->bAlternateSetting, msc->ep_bulk_in->bEndpointAddress, msc->ep_bulk_out->bEndpointAddress);
578 return umass_init_device(msc);
581static void msc_disconnect(IFACE_T *iface)
590 for(i = 0; i < iface->aif->ifd->bNumEndpoints; i++)
592 iface->udev->hc_driver->quit_xfer(
NULL, &(iface->aif->ep[i]));
602 if(msc->iface == iface)
604 fatfs_drive_free(msc->drv_no);
605 msc_list_remove(msc);
606 usbh_free_mem(msc,
sizeof(*msc));
612UDEV_DRV_T msc_driver =
634 return usbh_register_driver(&msc_driver);
NuMicro peripheral access layer header file.
#define UMAS_ERR_DRIVE_NOT_FOUND
#define USBH_ERR_NOT_MATCHED
#define USBH_ERR_NOT_SUPPORTED
#define USBH_ERR_NOT_FOUND
#define USBH_ERR_MEMORY_OUT
#define UMAS_ERR_IVALID_PARM
#define USBH_ERR_NOT_EXPECTED
int usbh_umas_read(int drv_no, uint32_t sec_no, int sec_cnt, uint8_t *buff)
int usbh_umas_write(int drv_no, uint32_t sec_no, int sec_cnt, uint8_t *buff)
HIDDEN_SYMBOLS int usbh_umas_init(void)
Register and initialize USB Host Mass Storage driver.
int usbh_umas_ioctl(int drv_no, int cmd, void *buff)
int usbh_umas_disk_status(int drv_no)
uint32_t get_ticks(void)
A function return current tick count.
USB Host mass storage class header.
int run_scsi_command(MSC_T *msc, uint8_t *buff, uint32_t data_len, int bIsDataIn, int timeout_ticks)
USB Host library header file.