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);
}
Example #2
0
File: diskio.c Project: gstroe/Arm
/**
 * \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;
}
Example #3
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;
}