Update Studio Integration DLL, to include package logging.
[pub/USBasp.git] / Bootloaders / MassStorage / Lib / SCSI.c
index 154fe48..0b76c66 100644 (file)
@@ -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)
 {