diff --git a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c
index 970df4f879a0eff425c303cebb5aa89b5889d48f..fbff2f48c71671f8bb9cc51348e8644e2cecd781 100644
--- a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c
+++ b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c
@@ -127,7 +127,9 @@ uint8_t SImage_RecieveBlockHeader(void)
 			}
 		}
 		
+		Pipe_Freeze();
 		Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);
+		Pipe_Unfreeze();
 
 		/* Check if pipe stalled (command failed by device) */
 		if (Pipe_IsStalled())
@@ -139,7 +141,9 @@ uint8_t SImage_RecieveBlockHeader(void)
 			return PIPE_RWSTREAM_PipeStalled;
 		}
 
+		Pipe_Freeze();
 		Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);
+		Pipe_Unfreeze();
 
 		/* Check if pipe stalled (command failed by device) */
 		if (Pipe_IsStalled())
@@ -155,14 +159,7 @@ uint8_t SImage_RecieveBlockHeader(void)
 		if (USB_HostState == HOST_STATE_Unattached)
 		  return PIPE_RWSTREAM_DeviceDisconnected;
 	}
-	
-	/* Freeze OUT pipe after use */
-	Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);
-	Pipe_Freeze();
-
-	/* Select the IN data pipe for data reception */
-	Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);
-	
+		
 	/* Load in the response from the attached device */
 	Pipe_Read_Stream_LE(&PIMA_ReceivedBlock, PIMA_COMMAND_SIZE(0));
 	
diff --git a/LUFA/Drivers/USB/Class/Common/StillImage.h b/LUFA/Drivers/USB/Class/Common/StillImage.h
index 2723aeb44fb34a9b7ab458741094cda1ba3d6b59..804b31255c6648c1cca3b8db15cda4024fb0ed59 100644
--- a/LUFA/Drivers/USB/Class/Common/StillImage.h
+++ b/LUFA/Drivers/USB/Class/Common/StillImage.h
@@ -66,15 +66,15 @@
 		 *
 		 *  \param[in] params  Number of parameters which are to be sent in the Param field of the container
 		 */
-		#define PIMA_COMMAND_SIZE(params)      ((sizeof(PIMA_SendBlock) - sizeof(PIMA_SendBlock.Params)) + \
-		                                        (params * sizeof(PIMA_SendBlock.Params[0])))
+		#define PIMA_COMMAND_SIZE(params)      ((sizeof(SI_PIMA_Container_t) - sizeof(((SI_PIMA_Container_t*)NULL)->Params)) + \
+		                                        (params * sizeof(((SI_PIMA_Container_t*)NULL)->Params[0])))
 
 		/** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
 		 *  a data container.
 		 *
 		 *  \param[in] datalen  Length in bytes of the data in the container
 		 */
-		#define PIMA_DATA_SIZE(datalen)        ((sizeof(PIMA_SendBlock) - sizeof(PIMA_SendBlock.Params)) + datalen)
+		#define PIMA_DATA_SIZE(datalen)        ((sizeof(SI_PIMA_Container_t) - sizeof(((SI_PIMA_Container_t*)NULL)->Params)) + datalen)
 
 	/* Type defines: */
 		/** Type define for a PIMA container, use to send commands and receive responses to and from an
@@ -101,7 +101,15 @@
 		};	
 		
 	/* Enums: */
-	
+		enum SI_PIMA_ResponseCodes_t
+		{
+			PIMA_RESPONSE_OK                     = 1,
+			PIMA_RESPONSE_GeneralError           = 2,
+			PIMA_RESPONSE_SessionNotOpen         = 3,
+			PIMA_RESPONSE_InvalidTransaction     = 4,
+			PIMA_RESPONSE_OperationNotSupported  = 5,
+			PIMA_RESPONSE_ParameterNotSupported  = 6,
+		};
 	
 	/* Type Defines: */
 	
diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.c b/LUFA/Drivers/USB/Class/Host/MassStorage.c
index 6a8373adcea0bdeeb4117be01da52a5e2ebe1da8..678c070c03680e93be01655365ea88e03dbdd2d8 100644
--- a/LUFA/Drivers/USB/Class/Host/MassStorage.c
+++ b/LUFA/Drivers/USB/Class/Host/MassStorage.c
@@ -95,9 +95,12 @@ static uint8_t DComp_NextMSInterface(void* CurrentDescriptor)
 {
 	if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
 	{
-		if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class    == MASS_STORE_CLASS)    &&
-		    (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == MASS_STORE_SUBCLASS) &&
-		    (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == MASS_STORE_PROTOCOL))
+		USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
+		                                                                USB_Descriptor_Interface_t);
+
+		if ((CurrentInterface->Class    == MASS_STORE_CLASS)    &&
+		    (CurrentInterface->SubClass == MASS_STORE_SUBCLASS) &&
+		    (CurrentInterface->Protocol == MASS_STORE_PROTOCOL))
 		{
 			return DESCRIPTOR_SEARCH_Found;
 		}
diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.c b/LUFA/Drivers/USB/Class/Host/StillImage.c
index ed38eae10fd59a42b297c6a0a4851e9a474224e0..10759f6bf4859f9a1ccd7289b27cc64db19e5b79 100644
--- a/LUFA/Drivers/USB/Class/Host/StillImage.c
+++ b/LUFA/Drivers/USB/Class/Host/StillImage.c
@@ -106,9 +106,12 @@ uint8_t DComp_SI_Host_NextSIInterface(void* CurrentDescriptor)
 {
 	if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
 	{
-		if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class    == STILL_IMAGE_CLASS)    &&
-		    (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == STILL_IMAGE_SUBCLASS) &&
-		    (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == STILL_IMAGE_PROTOCOL))
+		USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
+		                                                                USB_Descriptor_Interface_t);
+
+		if ((CurrentInterface->Class    == STILL_IMAGE_CLASS)    &&
+		    (CurrentInterface->SubClass == STILL_IMAGE_SUBCLASS) &&
+		    (CurrentInterface->Protocol == STILL_IMAGE_PROTOCOL))
 		{
 			return DESCRIPTOR_SEARCH_Found;
 		}
@@ -145,4 +148,144 @@ void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* SIInterfaceInfo)
 
 }
 
+void SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader)
+{
+	Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
+	Pipe_Unfreeze();
+
+	Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK);
+	
+	if (PIMAHeader->Type == CType_CommandBlock)
+	{
+		uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
+
+		if (ParamBytes)
+		  Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK);
+		
+		Pipe_ClearOUT();
+	}
+					
+	Pipe_Freeze();
+}
+
+uint8_t SImage_Host_RecieveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader)
+{
+	uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;
+
+	Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
+	Pipe_Unfreeze();
+	
+	while (!(Pipe_IsReadWriteAllowed()))
+	{
+		if (USB_INT_HasOccurred(USB_INT_HSOFI))
+		{
+			USB_INT_Clear(USB_INT_HSOFI);
+			TimeoutMSRem--;
+
+			if (!(TimeoutMSRem))
+			{
+				return PIPE_RWSTREAM_Timeout;
+			}
+		}
+		
+		Pipe_Freeze();
+		Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
+		Pipe_Unfreeze();
+
+		if (Pipe_IsStalled())
+		{
+			USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber);
+			return PIPE_RWSTREAM_PipeStalled;
+		}
+
+		Pipe_Freeze();
+		Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
+		Pipe_Unfreeze();
+
+		if (Pipe_IsStalled())
+		{
+			USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber);
+			return PIPE_RWSTREAM_PipeStalled;
+		}
+		  
+		if (USB_HostState == HOST_STATE_Unattached)
+		  return PIPE_RWSTREAM_DeviceDisconnected;
+	}
+	
+	Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK);
+	
+	if (PIMAHeader->Type == CType_ResponseBlock)
+	{
+		uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
+
+		if (ParamBytes)
+		  Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK);
+		
+		Pipe_ClearIN();
+	}
+	
+	Pipe_Freeze();
+	
+	return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes)
+{
+	uint8_t ErrorCode;
+
+	Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
+	Pipe_Unfreeze();
+	
+	ErrorCode = Pipe_Write_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
+
+	Pipe_ClearOUT();
+	Pipe_Freeze();
+	
+	return ErrorCode;
+}
+
+uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes)
+{
+	uint8_t ErrorCode;
+
+	Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
+	Pipe_Unfreeze();
+
+	ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
+
+	Pipe_Freeze();
+	
+	return ErrorCode;
+}
+
+bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo)
+{
+	bool IsEventReceived = false;
+
+	Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
+	Pipe_Unfreeze();
+	
+	if (Pipe_BytesInPipe())
+	  IsEventReceived = true;
+	
+	Pipe_Freeze();
+	
+	return IsEventReceived;
+}
+
+uint8_t SImage_Host_RecieveEventHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader)
+{
+	uint8_t ErrorCode;
+
+	Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
+	Pipe_Unfreeze();
+	
+	ErrorCode = Pipe_Read_Stream_LE(PIMAHeader, sizeof(SI_PIMA_Container_t), NO_STREAM_CALLBACK);
+	
+	Pipe_ClearIN();
+	Pipe_Freeze();
+	
+	return ErrorCode;
+}
+
 #endif
diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.h b/LUFA/Drivers/USB/Class/Host/StillImage.h
index d970594b34d72abab630b7c765ea1607f1a5ee46..f4d1bb14464ded80107ea6ee2454d7297e6e0205 100644
--- a/LUFA/Drivers/USB/Class/Host/StillImage.h
+++ b/LUFA/Drivers/USB/Class/Host/StillImage.h
@@ -119,6 +119,13 @@
 			 */
 			uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t ConfigDescriptorLength,
                                            uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3);
+
+			void SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader);
+			uint8_t SImage_Host_RecieveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader);
+			uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes);
+			uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes);
+			bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo);
+			uint8_t SImage_Host_RecieveEventHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader);
 							  
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 3280e8ed7da5d76ee7ddeed4f33c392fdb7d2da3..d62a31cc81518ed997423800ca69dba189ac05a4 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -47,6 +47,7 @@
   *  - Fixed Device mode HID Class driver always sending IN packets, even when nothing to report
   *  - Fixed Device mode HID Class driver not explicitly initializing the ReportSize parameter to zero before calling callback
   *    routine, so that ignored callbacks don't cause incorrect data to be sent
+  *  - Fixed StillImageHost not correctly freezing and unfreezing data pipes while waiting for a response block header
   *
   *
   *  \section Sec_ChangeLog090810 Version 090810