static void sbc_header_mode_sense (Bool b_sense_10, U8 u8_data_length) { Usb_reset_endpoint_fifo_access (g_scsi_ep_ms_in); // Send data length. if (b_sense_10) { Usb_write_endpoint_data (g_scsi_ep_ms_in, 8, 0); } Usb_write_endpoint_data (g_scsi_ep_ms_in, 8, u8_data_length); // Send device type. Usb_write_endpoint_data (g_scsi_ep_ms_in, 8, SBC_MEDIUM_TYPE); // Write protect status. Usb_write_endpoint_data (g_scsi_ep_ms_in, 8, (mem_wr_protect (usb_LUN)) ? SBC_DEV_SPEC_PARAM_WR_PROTECT : SBC_DEV_SPEC_PARAM_WR_ENABLE); if (b_sense_10) { // Reserved. Usb_write_endpoint_data (g_scsi_ep_ms_in, 16, 0); } // Send block descriptor length. if (b_sense_10) { Usb_write_endpoint_data (g_scsi_ep_ms_in, 8, 0); } Usb_write_endpoint_data (g_scsi_ep_ms_in, 8, SBC_BLOCK_DESCRIPTOR_LENGTH); }
/** * \brief Initialize a disk. * * \param drv Physical drive number (0..). * * \return 0 or disk status in combination of DSTATUS bits * (STA_NOINIT, STA_PROTECT). */ DSTATUS disk_initialize(BYTE drv) { int i; Ctrl_status mem_status; #if 0 /* Default RTC configuration, 24-hour mode */ rtc_set_hour_mode(RTC, 0); #endif #if 0 configure_rtc_calendar(); #endif #if LUN_USB /* USB disk with multiple LUNs */ if (drv > LUN_ID_USB + Lun_usb_get_lun()) { return STA_NOINIT; } #else if (drv > MAX_LUN) { /* At least one of the LUN should be defined */ return STA_NOINIT; } #endif /* Check LUN ready (USB disk report CTRL_BUSY then CTRL_GOOD) */ for (i = 0; i < 2; i ++) { mem_status = mem_test_unit_ready(drv); if (CTRL_BUSY != mem_status) { break; } } if (mem_status != CTRL_GOOD) { return STA_NOINIT; } /* Check Write Protection Status */ if (mem_wr_protect(drv)) { return STA_PROTECT; } /* The memory should already be initialized */ return 0; }
/** * \brief Initialize a disk. * * \param drv Physical drive number (0..). * * \return 0 or disk status in combination of DSTATUS bits * (STA_NOINIT, STA_PROTECT). */ DSTATUS disk_initialize(BYTE drv) { #if LUN_USB /* USB disk with multiple LUNs */ if (drv > LUN_ID_USB + Lun_usb_get_lun()) { return STA_NOINIT; } #else if (drv > MAX_LUN) { /* At least one of the LUN should be defined */ return STA_NOINIT; } #endif MutexLocker lock((drv >= SD_MMC_HSMCI_MEM_CNT) ? Tasks::GetSpiMutex() : nullptr); Ctrl_status mem_status; /* Check LUN ready (USB disk report CTRL_BUSY then CTRL_GOOD) */ for (int i = 0; i < 2; i ++) { mem_status = mem_test_unit_ready(drv); if (CTRL_BUSY != mem_status) { break; } } if (mem_status != CTRL_GOOD) { return STA_NOINIT; } /* Check Write Protection Status */ if (mem_wr_protect(drv)) { return STA_PROTECT; } /* The memory should already be initialized */ return 0; }
Bool sbc_write_10 (void) { U32 mass_addr; // Read/write block address. U16 mass_size; // Read/write number of blocks. // Read address. MSB0W (mass_addr) = g_scsi_command[2]; MSB1W (mass_addr) = g_scsi_command[3]; MSB2W (mass_addr) = g_scsi_command[4]; MSB3W (mass_addr) = g_scsi_command[5]; // Read size. MSB (mass_size) = g_scsi_command[7]; LSB (mass_size) = g_scsi_command[8]; if (ms_endpoint == EP_MS_IN) { // Error in command field sbc_lun_status_is_cdb_field (); return FALSE; } // No data to transfer. if (0 == g_scsi_data_remaining) { if (mass_size == (g_scsi_data_remaining / 512)) { sbc_lun_status_is_good (); } else { sbc_lun_status_is_cdb_field (); } return TRUE; } if (mem_wr_protect (usb_LUN)) { sbc_lun_status_is_protected (); return TRUE; // FALSE; } switch (usb_2_memory (usb_LUN, mass_addr, g_scsi_data_remaining / 512)) { case CTRL_GOOD: if (mass_size == (g_scsi_data_remaining / 512)) { sbc_lun_status_is_good (); } else { sbc_lun_status_is_cdb_field (); } g_scsi_data_remaining = 0; return TRUE; case CTRL_NO_PRESENT: sbc_lun_status_is_not_present (); break; case CTRL_BUSY: sbc_lun_status_is_busy_or_change (); break; case CTRL_FAIL: default: sbc_lun_status_is_fail (); break; } return FALSE; }