X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/0b1f33e2a26091714982447132b251496d5a48b2..3642ea0b9715cdf0196b10c9fc97898940eaefa6:/Bootloaders/MassStorage/Lib/SCSI.c diff --git a/Bootloaders/MassStorage/Lib/SCSI.c b/Bootloaders/MassStorage/Lib/SCSI.c index 154fe4885..0b76c66f3 100644 --- a/Bootloaders/MassStorage/Lib/SCSI.c +++ b/Bootloaders/MassStorage/Lib/SCSI.c @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2013. + Copyright (C) Dean Camera, 2015. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -86,7 +86,7 @@ static SCSI_Request_Sense_Response_t SenseData = * * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * - * \return Boolean true if the command completed successfully, false otherwise + * \return Boolean \c true if the command completed successfully, \c false otherwise */ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) { @@ -104,9 +104,6 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) case SCSI_CMD_READ_CAPACITY_10: CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo); break; - case SCSI_CMD_SEND_DIAGNOSTIC: - CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo); - break; case SCSI_CMD_WRITE_10: CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE); break; @@ -117,6 +114,11 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo); break; case SCSI_CMD_START_STOP_UNIT: +#if !defined(NO_APP_START_ON_EJECT) + /* If the user ejected the volume, signal bootloader exit at next opportunity. */ + RunBootloader = ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[4] & 0x03) != 0x02); +#endif + case SCSI_CMD_SEND_DIAGNOSTIC: case SCSI_CMD_TEST_UNIT_READY: case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: case SCSI_CMD_VERIFY_10: @@ -150,7 +152,7 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) * * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * - * \return Boolean true if the command completed successfully, false otherwise. + * \return Boolean \c true if the command completed successfully, \c false otherwise. */ static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) { @@ -188,7 +190,7 @@ static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInf * * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * - * \return Boolean true if the command completed successfully, false otherwise. + * \return Boolean \c true if the command completed successfully, \c false otherwise. */ static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) { @@ -210,15 +212,12 @@ static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterf * * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * - * \return Boolean true if the command completed successfully, false otherwise. + * \return Boolean \c true if the command completed successfully, \c false otherwise. */ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) { - uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1); - uint32_t MediaBlockSize = SECTOR_SIZE_BYTES; - - Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NULL); - Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NULL); + Endpoint_Write_32_BE(LUN_MEDIA_BLOCKS - 1); + Endpoint_Write_32_BE(SECTOR_SIZE_BYTES); Endpoint_ClearIN(); /* Succeed the command and update the bytes transferred counter */ @@ -227,33 +226,6 @@ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInt return true; } -/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the - * board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is - * supported. - * - * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with - * - * \return Boolean true if the command completed successfully, false otherwise. - */ -static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) -{ - /* Check to see if the SELF TEST bit is not set */ - if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2))) - { - /* Only self-test supported - update SENSE key and fail the command */ - SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, - SCSI_ASENSE_INVALID_FIELD_IN_CDB, - SCSI_ASENSEQ_NO_QUALIFIER); - - return false; - } - - /* Succeed the command and update the bytes transferred counter */ - MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; - - return true; -} - /** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address * and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual * reading and writing of the data. @@ -261,12 +233,12 @@ static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInte * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE) * - * \return Boolean true if the command completed successfully, false otherwise. + * \return Boolean \c true if the command completed successfully, \c false otherwise. */ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, const bool IsDataRead) { - uint32_t BlockAddress; + uint16_t BlockAddress; uint16_t TotalBlocks; /* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */ @@ -287,10 +259,13 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa } /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ - if (IsDataRead == DATA_READ) - VirtualFAT_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); - else - VirtualFAT_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); + for (uint16_t i = 0; i < TotalBlocks; i++) + { + if (IsDataRead == DATA_READ) + VirtualFAT_ReadBlock(BlockAddress + i); + else + VirtualFAT_WriteBlock(BlockAddress + i); + } /* Update the bytes transferred counter and succeed the command */ MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * SECTOR_SIZE_BYTES); @@ -303,7 +278,7 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa * * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * - * \return Boolean true if the command completed successfully, false otherwise. + * \return Boolean \c true if the command completed successfully, \c false otherwise. */ static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) {