/* Indicate device busy via the status LEDs */\r
UpdateStatus(Status_Busy);\r
\r
- /* Reset the Mass Storage device interface, ready for use */\r
- if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)\r
- {\r
- ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);\r
- break;\r
- }\r
- \r
/* Send the request, display error and wait for device detach if request fails */\r
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)\r
{ \r
- ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);\r
+ ShowDiskReadError(PSTR("Get Max LUN"), false, ErrorCode);\r
break;\r
}\r
\r
/* Print number of LUNs detected in the attached device */\r
printf_P(PSTR("Total LUNs: %d.\r\n"), (MassStore_MaxLUNIndex + 1));\r
-\r
- /* Set the prevent removal flag for the device, allowing it to be accessed */\r
- if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)\r
+ \r
+ /* Reset the Mass Storage device interface, ready for use */\r
+ if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)\r
{\r
- ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);\r
+ ShowDiskReadError(PSTR("Mass Storage Reset"), false, ErrorCode);\r
break;\r
}\r
\r
/* Get sense data from the device - many devices will not accept any other commands until the sense data\r
* is read - both on start-up and after a failed command */\r
SCSI_Request_Sense_Response_t SenseData;\r
- if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)\r
+ if (((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0) || (SCSICommandStatus.Status != Command_Pass))\r
+ {\r
+ ShowDiskReadError(PSTR("Request Sense"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);\r
+ break;\r
+ }\r
+ \r
+ /* Set the prevent removal flag for the device, allowing it to be accessed */\r
+ if (((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0) || (SCSICommandStatus.Status != Command_Pass))\r
{\r
- ShowDiskReadError(PSTR("Request Sense"), ErrorCode);\r
+ ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);\r
break;\r
}\r
\r
- puts_P(PSTR("Waiting until ready"));\r
+ puts_P(PSTR("Waiting until ready.."));\r
\r
/* Wait until disk ready */\r
do\r
{\r
Serial_TxByte('.');\r
- MassStore_TestUnitReady(0);\r
+ \r
+ if ((ErrorCode = MassStore_TestUnitReady(0)) != 0)\r
+ {\r
+ ShowDiskReadError(PSTR("Test Unit Ready"), false, ErrorCode);\r
+ break; \r
+ }\r
}\r
while ((SCSICommandStatus.Status != Command_Pass) && USB_IsConnected);\r
\r
SCSI_Capacity_t DiskCapacity;\r
\r
/* Retrieve disk capacity */\r
- if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)\r
+ if (((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0) || (SCSICommandStatus.Status != Command_Pass))\r
{\r
- ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);\r
+ ShowDiskReadError(PSTR("Read Capacity"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);\r
break;\r
}\r
\r
/* Display the disk capacity in blocks * block size bytes */\r
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);\r
- \r
+\r
/* Create a new buffer capabable of holding a single block from the device */\r
uint8_t BlockBuffer[DiskCapacity.BlockSize];\r
\r
/* Read in the first 512 byte block from the device */\r
- if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)\r
+ if (((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0) ||\r
+ (SCSICommandStatus.Status != Command_Pass))\r
{\r
- ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);\r
+ ShowDiskReadError(PSTR("Read Device Block"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);\r
break;\r
}\r
\r
- /* Show the number of bytes not transferred in the previous command */\r
- printf_P(PSTR("Transfer Residue: %lu\r\n"), SCSICommandStatus.DataTransferResidue);\r
- \r
puts_P(PSTR("\r\nContents of first block:\r\n"));\r
\r
/* Print out the first block in both HEX and ASCII, 16 bytes per line */\r
for (uint32_t CurrBlock = 0; CurrBlock < DiskCapacity.Blocks; CurrBlock++)\r
{\r
/* Read in the next block of data from the device */\r
- if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlock, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)\r
+ if (((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlock, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0) ||\r
+ (SCSICommandStatus.Status != Command_Pass))\r
{\r
- ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);\r
+ ShowDiskReadError(PSTR("Read Device Block"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);\r
break;\r
}\r
\r
* continuing.\r
*\r
* \param CommandString ASCII string located in PROGMEM space indicating what operation failed\r
+ * \param FailedAtSCSILayer Indicates if the command failed at the (logical) SCSI layer or at the physical USB layer\r
* \param ErrorCode Error code of the function which failed to complete successfully\r
*/\r
-void ShowDiskReadError(char* CommandString, uint8_t ErrorCode)\r
+void ShowDiskReadError(char* CommandString, bool FailedAtSCSILayer, uint8_t ErrorCode)\r
{\r
- /* Display the error code */\r
- printf_P(PSTR(ESC_BG_RED "Command error (%S).\r\n"), CommandString);\r
- printf_P(PSTR(" -- Error Code: %d"), ErrorCode);\r
- \r
+ if (CommandFailed)\r
+ {\r
+ /* Display the error code */\r
+ printf_P(PSTR(ESC_BG_RED "SCSI command error (%S).\r\n"), CommandString);\r
+ printf_P(PSTR(" -- Status Code: %d"), ErrorCode);\r
+ }\r
+ else\r
+ {\r
+ /* Display the error code */\r
+ printf_P(PSTR(ESC_BG_RED "Command error (%S).\r\n"), CommandString);\r
+ printf_P(PSTR(" -- Error Code: %d"), ErrorCode); \r
+ }\r
+\r
Pipe_Freeze();\r
\r
/* Indicate device error via the status LEDs */\r
\r
/* Send the data in the OUT pipe to the attached device */\r
Pipe_ClearOUT();\r
-\r
- /* Some buggy devices require a delay here before the pipe freezing or they will lock up */\r
- USB_Host_WaitMS(1);\r
\r
+ while(!(Pipe_IsOUTReady()));\r
+\r
/* Freeze pipe after use */\r
Pipe_Freeze();\r
\r
\r
/* Acknowledge the packet */\r
Pipe_ClearOUT();\r
+ \r
+ while (!(Pipe_IsOUTReady()));\r
}\r
-\r
- /* Some buggy devices require a delay here before the pipe freezing or they will lock up */\r
- USB_Host_WaitMS(1);\r
\r
/* Freeze used pipe after use */\r
Pipe_Freeze();\r
uint8_t ErrorCode = PIPE_RWSTREAM_ERROR_NoError;\r
\r
/* If an error in the command ocurred, abort */\r
- if ((ErrorCode == MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_ERROR_NoError)\r
+ if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_ERROR_NoError)\r
return ErrorCode;\r
\r
/* Select the IN data pipe for data reception */\r
\r
/* Clear the data ready for next reception */\r
Pipe_ClearIN();\r
-\r
- /* Some buggy devices require a delay here before the pipe freezing or they will lock up */\r
- USB_Host_WaitMS(1);\r
\r
/* Freeze the IN pipe after use */\r
Pipe_Freeze();\r
{\r
.Signature = CBW_SIGNATURE,\r
.Tag = MassStore_Tag,\r
- .DataTransferLength = 8,\r
+ .DataTransferLength = sizeof(SCSI_Capacity_t),\r
.Flags = COMMAND_DIRECTION_DATA_IN,\r
.LUN = LUNIndex,\r
.SCSICommandLength = 10\r
MassStore_SendCommand();\r
\r
/* Read in the returned CSW from the device */\r
- if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_ERROR_NoError)\r
+ if ((ReturnCode = MassStore_GetReturnedStatus()))\r
{\r
Pipe_Freeze();\r
return ReturnCode;\r