/*
LUFA Library
- Copyright (C) Dean Camera, 2010.
-
+ Copyright (C) Dean Camera, 2011.
+
dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
+ www.lufa-lib.org
*/
/*
- Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
- Permission to use, copy, modify, distribute, and sell this
+ Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
+ without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
*/
#define __INCLUDE_FROM_USB_DRIVER
-#include "../../HighLevel/USBMode.h"
+#include "../../Core/USBMode.h"
+
#if defined(USB_CAN_BE_HOST)
-#define __INCLUDE_FROM_MS_CLASS_HOST_C
#define __INCLUDE_FROM_MS_DRIVER
+#define __INCLUDE_FROM_MASSSTORAGE_HOST_C
#include "MassStorage.h"
uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
continue;
}
-
+
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
else
DataOUTEndpoint = EndpointData;
}
-
+
for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
{
+ uint16_t Size;
+ uint8_t Type;
+ uint8_t Token;
+ uint8_t EndpointAddress;
+ bool DoubleBanked;
+
if (PipeNum == MSInterfaceInfo->Config.DataINPipeNumber)
{
- Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
- DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
- MSInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
-
- MSInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ Size = le16_to_cpu(DataINEndpoint->EndpointSize);
+ EndpointAddress = DataINEndpoint->EndpointAddress;
+ Token = PIPE_TOKEN_IN;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = MSInterfaceInfo->Config.DataINPipeDoubleBank;
+
+ MSInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
}
else if (PipeNum == MSInterfaceInfo->Config.DataOUTPipeNumber)
{
- Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
- DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
- MSInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+ Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
+ EndpointAddress = DataOUTEndpoint->EndpointAddress;
+ Token = PIPE_TOKEN_OUT;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = MSInterfaceInfo->Config.DataOUTPipeDoubleBank;
- MSInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ MSInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!(Pipe_ConfigurePipe(PipeNum, Type, Token, EndpointAddress, Size,
+ DoubleBanked ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE)))
+ {
+ return MS_ENUMERROR_PipeConfigurationFailed;
}
}
static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor)
{
- if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
+ USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
+
+ if (Header->Type == DTYPE_Interface)
{
- USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
- USB_Descriptor_Interface_t);
+ USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
- if ((CurrentInterface->Class == MASS_STORE_CLASS) &&
- (CurrentInterface->SubClass == MASS_STORE_SUBCLASS) &&
- (CurrentInterface->Protocol == MASS_STORE_PROTOCOL))
+ if ((Interface->Class == MS_CSCP_MassStorageClass) &&
+ (Interface->SubClass == MS_CSCP_SCSITransparentSubclass) &&
+ (Interface->Protocol == MS_CSCP_BulkOnlyTransportProtocol))
{
return DESCRIPTOR_SEARCH_Found;
}
}
-
+
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor)
{
- if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
+ USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
+
+ if (Header->Type == DTYPE_Endpoint)
{
- USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
- USB_Descriptor_Endpoint_t);
+ USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
- uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
+ uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
- if ((EndpointType == EP_TYPE_BULK) &&
- (!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress))))
+ if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress))))
{
return DESCRIPTOR_SEARCH_Found;
}
}
- else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
+ else if (Header->Type == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
{
uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
- SCSICommandBlock->Signature = CBW_SIGNATURE;
- SCSICommandBlock->Tag = ++MSInterfaceInfo->State.TransactionTag;
-
- if (MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF)
+ if (++MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF)
MSInterfaceInfo->State.TransactionTag = 1;
+ SCSICommandBlock->Signature = CPU_TO_LE32(MS_CBW_SIGNATURE);
+ SCSICommandBlock->Tag = cpu_to_le32(MSInterfaceInfo->State.TransactionTag);
+
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t),
- NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ NULL)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearOUT();
Pipe_Freeze();
return ErrorCode;
}
-
+
return ErrorCode;
}
static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
{
- uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;
+ uint16_t TimeoutMSRem = MS_COMMAND_DATA_TIMEOUT_MS;
uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber();
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
while (!(Pipe_IsINReceived()))
{
uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber();
-
+
if (CurrentFrameNumber != PreviousFrameNumber)
{
PreviousFrameNumber = CurrentFrameNumber;
if (!(TimeoutMSRem--))
return PIPE_RWSTREAM_Timeout;
}
-
+
Pipe_Freeze();
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
return PIPE_RWSTREAM_PipeStalled;
}
-
+
Pipe_Freeze();
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
return PIPE_RWSTREAM_PipeStalled;
}
-
+
if (USB_HostState == HOST_STATE_Unattached)
return PIPE_RWSTREAM_DeviceDisconnected;
};
-
+
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
Pipe_Freeze();
-
+
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Freeze();
void* BufferPtr)
{
uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
- uint16_t BytesRem = SCSICommandBlock->DataTransferLength;
+ uint16_t BytesRem = le32_to_cpu(SCSICommandBlock->DataTransferLength);
- if (SCSICommandBlock->Flags & COMMAND_DIRECTION_DATA_IN)
+ if (SCSICommandBlock->Flags & MS_COMMAND_DIR_DATA_IN)
{
if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError)
{
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
-
- if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+
+ if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearIN();
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
- if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearOUT();
-
+
while (!(Pipe_IsOUTReady()))
{
if (USB_HostState == HOST_STATE_Unattached)
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
-
+
if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t),
- NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ NULL)) != PIPE_RWSTREAM_NoError)
{
return ErrorCode;
}
-
+
Pipe_ClearIN();
Pipe_Freeze();
-
+
if (SCSICommandStatus->Status != MS_SCSI_COMMAND_Pass)
ErrorCode = MS_ERROR_LOGICAL_CMD_FAILED;
-
+
return ErrorCode;
}
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
- .bRequest = REQ_MassStorageReset,
+ .bRequest = MS_REQ_MassStorageReset,
.wValue = 0,
.wIndex = MSInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
-
+
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL);
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
- .bRequest = REQ_GetMaxLUN,
+ .bRequest = MS_REQ_GetMaxLUN,
.wValue = 0,
.wIndex = MSInterfaceInfo->State.InterfaceNumber,
.wLength = 1,
};
-
+
Pipe_SelectPipe(PIPE_CONTROLPIPE);
- if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
+ if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled)
{
*MaxLUNIndex = 0;
- ErrorCode = HOST_SENDCONTROL_Successful;
+ ErrorCode = HOST_SENDCONTROL_Successful;
}
-
+
return ErrorCode;
}
{
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
-
+
uint8_t ErrorCode;
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
{
- .DataTransferLength = sizeof(SCSI_Inquiry_Response_t),
- .Flags = COMMAND_DIRECTION_DATA_IN,
+ .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Inquiry_Response_t)),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
.LUN = LUNIndex,
.SCSICommandLength = 6,
.SCSICommandData =
0x00 // Unused (control)
}
};
-
+
MS_CommandStatusWrapper_t SCSICommandStatus;
if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, InquiryData)) != PIPE_RWSTREAM_NoError)
- return ErrorCode;
-
+ return ErrorCode;
+
if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
{
- .DataTransferLength = 0,
- .Flags = COMMAND_DIRECTION_DATA_IN,
+ .DataTransferLength = CPU_TO_LE32(0),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
.LUN = LUNIndex,
.SCSICommandLength = 6,
.SCSICommandData =
0x00 // Unused (control)
}
};
-
+
MS_CommandStatusWrapper_t SCSICommandStatus;
if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError)
- return ErrorCode;
-
+ return ErrorCode;
+
if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
{
- .DataTransferLength = sizeof(SCSI_Capacity_t),
- .Flags = COMMAND_DIRECTION_DATA_IN,
+ .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Capacity_t)),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
.LUN = LUNIndex,
.SCSICommandLength = 10,
.SCSICommandData =
0x00 // Unused (control)
}
};
-
+
MS_CommandStatusWrapper_t SCSICommandStatus;
if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, DeviceCapacity)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
- SwapEndian_n(&DeviceCapacity->Blocks, sizeof(DeviceCapacity->Blocks));
- SwapEndian_n(&DeviceCapacity->BlockSize, sizeof(DeviceCapacity->BlockSize));
-
+ DeviceCapacity->Blocks = BE32_TO_CPU(DeviceCapacity->Blocks);
+ DeviceCapacity->BlockSize = BE32_TO_CPU(DeviceCapacity->BlockSize);
+
if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
{
- .DataTransferLength = sizeof(SCSI_Request_Sense_Response_t),
- .Flags = COMMAND_DIRECTION_DATA_IN,
+ .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Request_Sense_Response_t)),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
.LUN = LUNIndex,
.SCSICommandLength = 6,
.SCSICommandData =
0x00 // Unused (control)
}
};
-
+
MS_CommandStatusWrapper_t SCSICommandStatus;
if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, SenseData)) != PIPE_RWSTREAM_NoError)
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
{
- .DataTransferLength = 0,
- .Flags = COMMAND_DIRECTION_DATA_OUT,
+ .DataTransferLength = CPU_TO_LE32(0),
+ .Flags = MS_COMMAND_DIR_DATA_OUT,
.LUN = LUNIndex,
.SCSICommandLength = 6,
.SCSICommandData =
0x00 // Unused (control)
}
};
-
+
MS_CommandStatusWrapper_t SCSICommandStatus;
if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
-
+
if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
{
- .DataTransferLength = ((uint32_t)Blocks * BlockSize),
- .Flags = COMMAND_DIRECTION_DATA_IN,
+ .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
.LUN = LUNIndex,
.SCSICommandLength = 10,
.SCSICommandData =
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
{
- .DataTransferLength = ((uint32_t)Blocks * BlockSize),
- .Flags = COMMAND_DIRECTION_DATA_OUT,
+ .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize),
+ .Flags = MS_COMMAND_DIR_DATA_OUT,
.LUN = LUNIndex,
.SCSICommandLength = 10,
.SCSICommandData =
if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
-
+
if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
}
#endif
+