kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/transport/cbulkonlytransport.cpp
changeset 297 b2826f67641f
parent 90 947f0dc9f7a8
equal deleted inserted replaced
296:94f2adf59133 297:b2826f67641f
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    34 #include "mdevicetransport.h"
    34 #include "mdevicetransport.h"
    35 
    35 
    36 #include "mstypes.h"
    36 #include "mstypes.h"
    37 #include "botcontrolinterface.h"
    37 #include "botcontrolinterface.h"
    38 #include "debug.h"
    38 #include "debug.h"
    39 #include "msdebug.h"
       
    40 #include "cusbmassstorageserver.h"
    39 #include "cusbmassstorageserver.h"
    41 #include "cusbmassstoragecontroller.h"
    40 #include "cusbmassstoragecontroller.h"
    42 #include "drivemanager.h"
    41 #include "drivemanager.h"
    43 #include "cbulkonlytransport.h"
    42 #include "cbulkonlytransport.h"
    44 
    43 
    53 @param aController - reference to the parent
    52 @param aController - reference to the parent
    54 @return pointer to newly created object
    53 @return pointer to newly created object
    55 */
    54 */
    56 CBulkOnlyTransport* CBulkOnlyTransport::NewL(TInt aNumDrives,
    55 CBulkOnlyTransport* CBulkOnlyTransport::NewL(TInt aNumDrives,
    57                                              CUsbMassStorageController& aController)
    56                                              CUsbMassStorageController& aController)
    58 	{
    57     {
    59     __MSFNSLOG
    58     if (aNumDrives <=0 || static_cast<TUint>(aNumDrives) > KUsbMsMaxDrives)
    60 	if (aNumDrives <=0 || static_cast<TUint>(aNumDrives) > KUsbMsMaxDrives)
    59         {
    61 		{
    60         User::Leave(KErrArgument);
    62 		User::Leave(KErrArgument);
    61         }
    63 		}
    62     CBulkOnlyTransport* self = new(ELeave) CBulkOnlyTransport(aNumDrives, aController);
    64 	CBulkOnlyTransport* self = new(ELeave) CBulkOnlyTransport(aNumDrives, aController);
    63     CleanupStack::PushL(self);
    65 	CleanupStack::PushL(self);
    64     self->ConstructL();
    66 	self->ConstructL();
    65     CleanupStack::Pop(self);
    67 	CleanupStack::Pop(self);
    66     return self;
    68 	return self;
    67     }
    69 	}
       
    70 
    68 
    71 #ifdef MSDC_TESTMODE
    69 #ifdef MSDC_TESTMODE
    72 CBulkOnlyTransport* CBulkOnlyTransport::NewL(TInt aNumDrives,
    70 CBulkOnlyTransport* CBulkOnlyTransport::NewL(TInt aNumDrives,
    73                                              CUsbMassStorageController& aController,
    71                                              CUsbMassStorageController& aController,
    74                                              TTestParser* aTestParser)
    72                                              TTestParser* aTestParser)
    75 	{
    73     {
    76     __MSFNSLOG
    74     if (aNumDrives <=0 || static_cast<TUint>(aNumDrives) > KUsbMsMaxDrives)
    77 	if (aNumDrives <=0 || static_cast<TUint>(aNumDrives) > KUsbMsMaxDrives)
    75         {
    78 		{
    76         User::Leave(KErrArgument);
    79 		User::Leave(KErrArgument);
    77         }
    80 		}
    78     CBulkOnlyTransport* self = new(ELeave) CBulkOnlyTransport(aNumDrives,
    81 	CBulkOnlyTransport* self = new(ELeave) CBulkOnlyTransport(aNumDrives,
       
    82                                                               aController,
    79                                                               aController,
    83                                                               aTestParser);
    80                                                               aTestParser);
    84 	CleanupStack::PushL(self);
    81     CleanupStack::PushL(self);
    85 	self->ConstructL();
    82     self->ConstructL();
    86 	CleanupStack::Pop(self);
    83     CleanupStack::Pop(self);
    87 	return self;
    84     return self;
    88 	}
    85     }
    89 #endif
    86 #endif
    90 
    87 
    91 
    88 
    92 /**
    89 /**
    93 c'tor
    90 c'tor
    94 @param aNumDrives - The number of drives available for MS
    91 @param aNumDrives - The number of drives available for MS
    95 @param aController - reference to the parent
    92 @param aController - reference to the parent
    96 */
    93 */
    97 CBulkOnlyTransport::CBulkOnlyTransport(TInt aNumDrives,
    94 CBulkOnlyTransport::CBulkOnlyTransport(TInt aNumDrives,
    98                                        CUsbMassStorageController& aController):
    95                                        CUsbMassStorageController& aController):
    99 	CActive(EPriorityStandard),
    96     CActive(EPriorityStandard),
   100 	iMaxLun(aNumDrives-1),
    97     iMaxLun(aNumDrives-1),
   101 	iController(aController),
    98     iController(aController),
   102 	iStallAllowed(ETrue)
    99     iStallAllowed(ETrue)
   103 	{
   100     {
   104     __MSFNLOG
   101     }
   105 	}
       
   106 
   102 
   107 #ifdef MSDC_TESTMODE
   103 #ifdef MSDC_TESTMODE
   108 CBulkOnlyTransport::CBulkOnlyTransport(TInt aNumDrives,
   104 CBulkOnlyTransport::CBulkOnlyTransport(TInt aNumDrives,
   109                                        CUsbMassStorageController& aController,
   105                                        CUsbMassStorageController& aController,
   110                                        TTestParser* aTestParser)
   106                                        TTestParser* aTestParser)
   111 :   CActive(EPriorityStandard),
   107 :   CActive(EPriorityStandard),
   112 	iMaxLun(aNumDrives-1),
   108     iMaxLun(aNumDrives-1),
   113 	iController(aController),
   109     iController(aController),
   114 	iStallAllowed(ETrue),
   110     iStallAllowed(ETrue),
   115     iTestParser(aTestParser)
   111     iTestParser(aTestParser)
   116 	{
   112     {
   117     __MSFNLOG
   113     }
   118 	}
       
   119 #endif
   114 #endif
   120 
   115 
   121 
   116 
   122 /**
   117 /**
   123 Constructs the CBulkOnlyTranspor object
   118 Constructs the CBulkOnlyTranspor object
   124 */
   119 */
   125 void CBulkOnlyTransport::ConstructL()
   120 void CBulkOnlyTransport::ConstructL()
   126 	{
   121     {
   127     __MSFNLOG
   122     iBotControlInterface = CBotControlInterface::NewL(*this);
   128 	iBotControlInterface = CBotControlInterface::NewL(*this);
   123     iDeviceStateNotifier = CActiveDeviceStateNotifier::NewL(*this);
   129 	iDeviceStateNotifier = CActiveDeviceStateNotifier::NewL(*this);
   124     CActiveScheduler::Add(this);
   130 	CActiveScheduler::Add(this);
   125     }
   131 	}
       
   132 
   126 
   133 
   127 
   134 /**
   128 /**
   135 Destructor
   129 Destructor
   136 */
   130 */
   137 CBulkOnlyTransport::~CBulkOnlyTransport()
   131 CBulkOnlyTransport::~CBulkOnlyTransport()
   138 	{
   132     {
   139     __MSFNLOG
   133     if (iInterfaceConfigured)
   140 	if (iInterfaceConfigured)
   134         {
   141 		{
   135         Stop();
   142 		Stop();
   136         }
   143 		}
   137     delete iBotControlInterface;
   144 	delete iBotControlInterface;
   138     delete iDeviceStateNotifier;
   145 	delete iDeviceStateNotifier;
   139     }
   146 	}
       
   147 
   140 
   148 
   141 
   149 /**
   142 /**
   150 Set or unset configuration descriptor for USB MassStorage Bulk Only transport
   143 Set or unset configuration descriptor for USB MassStorage Bulk Only transport
   151 
   144 
   152 @param aUnset indicate whether set or unset descriptor
   145 @param aUnset indicate whether set or unset descriptor
   153 @return KErrNone if operation was completed successfully, errorcode otherwise
   146 @return KErrNone if operation was completed successfully, errorcode otherwise
   154 */
   147 */
   155 TInt CBulkOnlyTransport::SetupConfigurationDescriptor(TBool aUnset)
   148 TInt CBulkOnlyTransport::SetupConfigurationDescriptor(TBool aUnset)
   156 	{
   149     {
   157     __MSFNLOG
   150     TInt ret(KErrNone);
   158 	TInt ret(KErrNone);
   151     TInt configDescriptorSize(0);
   159 	TInt configDescriptorSize(0);
   152 
   160 
   153     iLdd.GetConfigurationDescriptorSize(configDescriptorSize);
   161 	iLdd.GetConfigurationDescriptorSize(configDescriptorSize);
   154     if (static_cast<TUint>(configDescriptorSize) != KUsbDescSize_Config)
   162 	if (static_cast<TUint>(configDescriptorSize) != KUsbDescSize_Config)
   155         {
   163 		{
   156         return KErrCorrupt;
   164 		return KErrCorrupt;
   157         }
   165 		}
   158 
   166 
   159     TBuf8<KUsbDescSize_Config> configDescriptor;
   167 	TBuf8<KUsbDescSize_Config> configDescriptor;
   160     ret = iLdd.GetConfigurationDescriptor(configDescriptor);
   168 	ret = iLdd.GetConfigurationDescriptor(configDescriptor);
   161     if (ret != KErrNone)
   169 	if (ret != KErrNone)
   162         {
   170 		{
   163         return ret;
   171 		return ret;
   164         }
   172 		}
   165 
   173 
   166     // I beleive that other fields setted up during LDD initialisation
   174 	// I beleive that other fields setted up during LDD initialisation
   167     if (aUnset)
   175 	if (aUnset)
   168         {
   176 		{
   169         --configDescriptor[KUsbNumInterfacesOffset];
   177 		--configDescriptor[KUsbNumInterfacesOffset];
   170         }
   178 		}
   171     else
   179 	else
   172         {
   180 		{
   173         ++configDescriptor[KUsbNumInterfacesOffset];
   181 		++configDescriptor[KUsbNumInterfacesOffset];
   174         }
   182 		}
   175     ret = iLdd.SetConfigurationDescriptor(configDescriptor);
   183 	ret = iLdd.SetConfigurationDescriptor(configDescriptor);
   176 
   184 
   177     return ret;
   185 	return ret;
   178     }
   186 	}
       
   187 
   179 
   188 
   180 
   189 /**
   181 /**
   190 Set up interface descriptor
   182 Set up interface descriptor
   191 
   183 
   192 @return KErrNone if operation was completed successfully, errorcode otherwise
   184 @return KErrNone if operation was completed successfully, errorcode otherwise
   193 */
   185 */
   194 TInt CBulkOnlyTransport::SetupInterfaceDescriptors()
   186 TInt CBulkOnlyTransport::SetupInterfaceDescriptors()
   195 	{
   187     {
   196     __MSFNLOG
   188     // Device caps
   197 	// Device caps
   189     TUsbDeviceCaps d_caps;
   198 	TUsbDeviceCaps d_caps;
   190     TInt ret = iLdd.DeviceCaps(d_caps);
   199 	TInt ret = iLdd.DeviceCaps(d_caps);
   191     if (ret != KErrNone)
   200 	if (ret != KErrNone)
   192         {
   201 		{
   193         return ret;
   202 		return ret;
   194         }
   203 		}
   195     TInt totalEndpoints = d_caps().iTotalEndpoints;
   204 	TInt totalEndpoints = d_caps().iTotalEndpoints;
   196     if (totalEndpoints  < KRequiredNumberOfEndpoints)
   205 	if (totalEndpoints  < KRequiredNumberOfEndpoints)
   197         {
   206 		{
   198         return KErrHardwareNotAvailable;
   207 		return KErrHardwareNotAvailable;
   199         }
   208 		}
   200 
   209 
   201     // Endpoint caps
   210 	// Endpoint caps
   202     TUsbcEndpointData data[KUsbcMaxEndpoints];
   211 	TUsbcEndpointData data[KUsbcMaxEndpoints];
   203     TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
   212 	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
   204     ret = iLdd.EndpointCaps(dataptr);
   213 	ret = iLdd.EndpointCaps(dataptr);
   205     if (ret != KErrNone)
   214 	if (ret != KErrNone)
   206         {
   215 		{
   207         return ret;
   216 		return ret;
   208         }
   217 		}
   209 
   218 
   210     // Set the active interface
   219 	// Set the active interface
   211     TUsbcInterfaceInfoBuf ifc;
   220 	TUsbcInterfaceInfoBuf ifc;
   212     TInt ep_found = 0;
   221 	TInt ep_found = 0;
   213     TBool foundBulkIN = EFalse;
   222 	TBool foundBulkIN = EFalse;
   214     TBool foundBulkOUT = EFalse;
   223 	TBool foundBulkOUT = EFalse;
   215 
   224 
   216     for (TInt i = 0; i < totalEndpoints ; i++)
   225 	for (TInt i = 0; i < totalEndpoints ; i++)
   217         {
   226 		{
   218         const TUsbcEndpointCaps* caps = &data[i].iCaps;
   227 		const TUsbcEndpointCaps* caps = &data[i].iCaps;
   219         const TInt maxPacketSize = caps->MaxPacketSize();
   228 		const TInt maxPacketSize = caps->MaxPacketSize();
   220         if (!foundBulkIN &&
   229 		if (!foundBulkIN &&
   221             (caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) == (KUsbEpTypeBulk | KUsbEpDirIn))
   230 			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) == (KUsbEpTypeBulk | KUsbEpDirIn))
   222             {
   231 			{
   223             // KInEndpoint is going to be our TX (IN, write) endpoint
   232 			// KInEndpoint is going to be our TX (IN, write) endpoint
   224             ifc().iEndpointData[0].iType = KUsbEpTypeBulk;
   233 			ifc().iEndpointData[0].iType = KUsbEpTypeBulk;
   225             if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) == KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
   234 			if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) == KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
   226                 ifc().iEndpointData[0].iFeatureWord1  = KUsbcEndpointInfoFeatureWord1_DMA|KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
   235 				ifc().iEndpointData[0].iFeatureWord1  = KUsbcEndpointInfoFeatureWord1_DMA|KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
   227             ifc().iEndpointData[0].iDir  = KUsbEpDirIn;
   236 			ifc().iEndpointData[0].iDir  = KUsbEpDirIn;
   228             ifc().iEndpointData[0].iSize = maxPacketSize;
   237 			ifc().iEndpointData[0].iSize = maxPacketSize;
   229             ifc().iEndpointData[0].iInterval_Hs = 0;
   238 			ifc().iEndpointData[0].iInterval_Hs = 0;
   230             foundBulkIN = ETrue;
   239 			foundBulkIN = ETrue;
   231             if (++ep_found == KRequiredNumberOfEndpoints)
   240 			if (++ep_found == KRequiredNumberOfEndpoints)
   232                 {
   241 				{
   233                 break;
   242 				break;
   234                 }
   243 				}
   235             continue;
   244 			continue;
   236             }
   245 			}
   237         if (!foundBulkOUT &&
   246 		if (!foundBulkOUT &&
   238             (caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) == (KUsbEpTypeBulk | KUsbEpDirOut))
   247 			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) == (KUsbEpTypeBulk | KUsbEpDirOut))
   239             {
   248 			{
   240             // KOutEndpoint is going to be our RX (OUT, read) endpoint
   249 			// KOutEndpoint is going to be our RX (OUT, read) endpoint
   241             ifc().iEndpointData[1].iType = KUsbEpTypeBulk;
   250 			ifc().iEndpointData[1].iType = KUsbEpTypeBulk;
   242             if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) == KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
   251 			if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) == KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
   243                 ifc().iEndpointData[1].iFeatureWord1  = KUsbcEndpointInfoFeatureWord1_DMA|KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
   252 				ifc().iEndpointData[1].iFeatureWord1  = KUsbcEndpointInfoFeatureWord1_DMA|KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
   244             ifc().iEndpointData[1].iDir  = KUsbEpDirOut;
   253 			ifc().iEndpointData[1].iDir  = KUsbEpDirOut;
   245             ifc().iEndpointData[1].iSize = maxPacketSize;
   254 			ifc().iEndpointData[1].iSize = maxPacketSize;
   246             ifc().iEndpointData[1].iInterval_Hs = 0;
   255 			ifc().iEndpointData[1].iInterval_Hs = 0;
   247             foundBulkOUT = ETrue;
   256 			foundBulkOUT = ETrue;
   248             if (++ep_found == KRequiredNumberOfEndpoints)
   257 			if (++ep_found == KRequiredNumberOfEndpoints)
   249                 {
   258 				{
   250                 break;
   259 				break;
   251                 }
   260 				}
   252             continue;
   261 			continue;
   253             }
   262 			}
   254         }
   263 		}
   255     if (ep_found != KRequiredNumberOfEndpoints)
   264 	if (ep_found != KRequiredNumberOfEndpoints)
   256         {
   265 		{
   257         return KErrHardwareNotAvailable;
   266 		return KErrHardwareNotAvailable;
   258         }
   267 		}
   259 
   268 
   260     _LIT16(string, "USB Mass Storage Interface");
   269 	_LIT16(string, "USB Mass Storage Interface");
   261     ifc().iString = const_cast<TDesC16*>(&string);
   270 	ifc().iString = const_cast<TDesC16*>(&string);
   262     ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
   271 	ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
   263     ifc().iClass.iClassNum    = 0x08;   // Mass Storage
   272 	ifc().iClass.iClassNum    = 0x08;	// Mass Storage
   264     ifc().iClass.iSubClassNum = 0x06;   // SCSI Transparent Command Set
   273 	ifc().iClass.iSubClassNum = 0x06;	// SCSI Transparent Command Set
   265     ifc().iClass.iProtocolNum = 0x50;   // Bulk Only Transport
   274 	ifc().iClass.iProtocolNum = 0x50;	// Bulk Only Transport
   266 
   275 
   267     TUint bandwidth_priority = (EUsbcBandwidthOUTDefault | EUsbcBandwidthINDefault);
   276 	TUint bandwidth_priority = (EUsbcBandwidthOUTDefault | EUsbcBandwidthINDefault);
   268     if (d_caps().iHighSpeed)
   277 	if (d_caps().iHighSpeed)
   269         {
   278 		{
   270         // If this device supports USB High-speed, then we request 64KB buffers
   279 		// If this device supports USB High-speed, then we request 64KB buffers
   271         // (otherwise the default 4KB ones will do).
   280 		// (otherwise the default 4KB ones will do).
   272         bandwidth_priority = (EUsbcBandwidthOUTPlus2 | EUsbcBandwidthINPlus2);
   281 		bandwidth_priority = (EUsbcBandwidthOUTPlus2 | EUsbcBandwidthINPlus2);
   273         // Also, tell the Protocol about it, because it might want to do some
   282 		// Also, tell the Protocol about it, because it might want to do some
   274         // optimizing too.
   283 		// optimizing too.
   275         iProtocol->ReportHighSpeedDevice();
   284 		iProtocol->ReportHighSpeedDevice();
   276         }
   285 		}
   277     ret = iLdd.SetInterface(0, ifc, bandwidth_priority);
   286 	ret = iLdd.SetInterface(0, ifc, bandwidth_priority);
   278     return ret;
   287 	return ret;
   279     }
   288 	}
       
   289 
   280 
   290 
   281 
   291 /**
   282 /**
   292 Called by the protocol after processing the packet to indicate that more data is required.
   283 Called by the protocol after processing the packet to indicate that more data is required.
   293 
   284 
   294 @param aData reference to the data buffer.
   285 @param aData reference to the data buffer.
   295 */
   286 */
   296 void CBulkOnlyTransport::SetupDataOut(TPtr8& aData)
   287 void CBulkOnlyTransport::SetupDataOut(TPtr8& aData)
   297     {
   288     {
   298     __MSFNLOG
       
   299     iDataTransferMan.SetModeDataOut(aData);
   289     iDataTransferMan.SetModeDataOut(aData);
   300     }
   290     }
   301 
   291 
   302 /**
   292 /**
   303 Called by the protocol after processing the packet to indicate that data should be written to the host.
   293 Called by the protocol after processing the packet to indicate that data should be written to the host.
   304 
   294 
   305 @param aData reference to the data buffer.
   295 @param aData reference to the data buffer.
   306 */
   296 */
   307 void CBulkOnlyTransport::SetupDataIn(TPtrC8& aData)
   297 void CBulkOnlyTransport::SetupDataIn(TPtrC8& aData)
   308 	{
   298     {
   309     iDataTransferMan.SetModeDataIn(aData);
   299     iDataTransferMan.SetModeDataIn(aData);
   310 	}
   300     }
   311 
   301 
   312 
   302 
   313 TInt CBulkOnlyTransport::Start()
   303 TInt CBulkOnlyTransport::Start()
   314 	{
   304     {
   315     __MSFNLOG
   305     TInt err = KErrNone;
   316 	TInt err = KErrNone;
   306 
   317 
   307     if (!iProtocol)
   318 	if (!iProtocol)
   308         {
   319 		{
   309         return KErrBadHandle;   //protocol should be set up before start
   320 		return KErrBadHandle;   //protocol should be set up before start
   310         }
   321 		}
   311 
   322 
   312     if (IsActive())
   323 	if (IsActive())
   313         {
   324 		{
   314         __PRINT(_L("CBulkOnlyTransport::Start  - active before start!\n"));
   325 		__PRINT(_L("CBulkOnlyTransport::Start  - active before start!\n"));
   315         return KErrInUse;
   326 		return KErrInUse;
   316         }
   327 		}
   317 
   328 
   318     if ((err = iLdd.Open(0))                    != KErrNone ||
   329 	if ((err = iLdd.Open(0))					!= KErrNone ||
   319         (err = SetupConfigurationDescriptor())  != KErrNone ||
   330 		(err = SetupConfigurationDescriptor()) 	!= KErrNone ||
   320         (err = SetupInterfaceDescriptors())     != KErrNone )
   331 		(err = SetupInterfaceDescriptors())		!= KErrNone )
   321         {
   332 		{
   322         __PRINT(_L("CBulkOnlyTransport::Start  - Error during descriptors setup!\n"));
   333 		__PRINT(_L("CBulkOnlyTransport::Start  - Error during descriptors setup!\n"));
   323         return err;
   334 		return err;
   324         }
   335 		}
   325 
   336 
   326     iDeviceStateNotifier->Activate();  // activate notifier wich will wait until USB became configured
   337 	iDeviceStateNotifier->Activate();  // activate notifier wich will wait until USB became configured
   327     TUsbcDeviceState deviceStatus = EUsbcDeviceStateDefault;
   338 	TUsbcDeviceState deviceStatus = EUsbcDeviceStateDefault;
   328     err = iLdd.DeviceStatus(deviceStatus);
   339 	err = iLdd.DeviceStatus(deviceStatus);
   329     __PRINT1(_L("CBulkOnlyTransport::Start - Device status = %d\n"), deviceStatus);
   340 	__PRINT1(_L("CBulkOnlyTransport::Start - Device status = %d\n"), deviceStatus);
   330     if (err == KErrNone && deviceStatus == EUsbcDeviceStateConfigured)
   341 	if (err == KErrNone && deviceStatus == EUsbcDeviceStateConfigured)
   331         {
   342 		{
   332         __PRINT(_L("CBulkOnlyTransport::Start  - Starting bulk only transport\n"));
   343 		__PRINT(_L("CBulkOnlyTransport::Start  - Starting bulk only transport\n"));
   333         err = HwStart();
   344 		err = HwStart();
   334         }
   345 		}
   335     iInterfaceConfigured = ETrue;
   346 	iInterfaceConfigured = ETrue;
   336     return err;
   347 	return err;
   337     }
   348 	}
       
   349 
   338 
   350 TInt CBulkOnlyTransport::HwStart(TBool aDiscard)
   339 TInt CBulkOnlyTransport::HwStart(TBool aDiscard)
   351 	{
   340     {
   352     __MSFNLOG
       
   353 
       
   354     TInt lun = MaxLun();
   341     TInt lun = MaxLun();
   355     do
   342     do
   356         {
   343         {
   357         Controller().DriveManager().Connect(lun);
   344         Controller().DriveManager().Connect(lun);
   358         }
   345         }
   359     while(--lun >= 0);
   346     while(--lun >= 0);
   360 
   347 
   361 	TInt res = iBotControlInterface->Start() ;
   348     TInt res = iBotControlInterface->Start() ;
   362 
   349 
   363 	iCurrentState = ENone;
   350     iCurrentState = ENone;
   364     iDataTransferMan.Init();
   351     iDataTransferMan.Init();
   365 	iStarted = ETrue;
   352     iStarted = ETrue;
   366 
   353 
   367 	TUsbDeviceCaps d_caps;
   354     TUsbDeviceCaps d_caps;
   368 	TInt ret = iLdd.DeviceCaps(d_caps);
   355     TInt ret = iLdd.DeviceCaps(d_caps);
   369 	if (ret == KErrNone)
   356     if (ret == KErrNone)
   370 		{
   357         {
   371 		if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
   358         if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
   372 			{
   359             {
   373 			// Set up DMA if possible (errors are non-critical)
   360             // Set up DMA if possible (errors are non-critical)
   374 			TInt err = iLdd.AllocateEndpointResource(KOutEndpoint, EUsbcEndpointResourceDMA);
   361             TInt err = iLdd.AllocateEndpointResource(KOutEndpoint, EUsbcEndpointResourceDMA);
   375 			if (err != KErrNone)
   362             if (err != KErrNone)
   376 				{
   363                 {
   377 				__PRINT1(_L("Set DMA on OUT endpoint failed with error code: %d"), err);
   364                 __PRINT1(_L("Set DMA on OUT endpoint failed with error code: %d"), err);
   378 				}
   365                 }
   379 			err = iLdd.AllocateEndpointResource(KInEndpoint, EUsbcEndpointResourceDMA);
   366             err = iLdd.AllocateEndpointResource(KInEndpoint, EUsbcEndpointResourceDMA);
   380 			if (err != KErrNone)
   367             if (err != KErrNone)
   381 				{
   368                 {
   382 				__PRINT1(_L("Set DMA on IN endpoint failed with error code: %d"), err);
   369                 __PRINT1(_L("Set DMA on IN endpoint failed with error code: %d"), err);
   383 				}
   370                 }
   384 
   371 
   385 			// Set up Double Buffering if possible (errors are non-critical)
   372             // Set up Double Buffering if possible (errors are non-critical)
   386 			err = iLdd.AllocateEndpointResource(KOutEndpoint, EUsbcEndpointResourceDoubleBuffering);
   373             err = iLdd.AllocateEndpointResource(KOutEndpoint, EUsbcEndpointResourceDoubleBuffering);
   387 			if (err != KErrNone)
   374             if (err != KErrNone)
   388 				{
   375                 {
   389 				__PRINT1(_L("Set Double Buffering on OUT endpoint failed with error code: %d"), err);
   376                 __PRINT1(_L("Set Double Buffering on OUT endpoint failed with error code: %d"), err);
   390 				}
   377                 }
   391 			err = iLdd.AllocateEndpointResource(KInEndpoint, EUsbcEndpointResourceDoubleBuffering);
   378             err = iLdd.AllocateEndpointResource(KInEndpoint, EUsbcEndpointResourceDoubleBuffering);
   392 			if (err != KErrNone)
   379             if (err != KErrNone)
   393 				{
   380                 {
   394 				__PRINT1(_L("Set Double Buffering on IN endpoint failed with error code: %d"), err);
   381                 __PRINT1(_L("Set Double Buffering on IN endpoint failed with error code: %d"), err);
   395 				}
   382                 }
   396 			}
   383             }
   397 		}
   384         }
   398 
   385 
   399     if (aDiscard)
   386     if (aDiscard)
   400 		{
   387         {
   401 		TInt bytes;
   388         TInt bytes;
   402 		const TInt err = iLdd.QueryReceiveBuffer(KOutEndpoint, bytes);
   389         const TInt err = iLdd.QueryReceiveBuffer(KOutEndpoint, bytes);
   403 		if (err != KErrNone || bytes <= 0)
   390         if (err != KErrNone || bytes <= 0)
   404 			{
   391             {
   405 			__PRINT1(_L("Error: err=%d bytes=%d"), bytes);
   392             __PRINT1(_L("Error: err=%d bytes=%d"), bytes);
   406 			}
   393             }
   407 		else
   394         else
   408 			{
   395             {
   409 			__PRINT1(_L("RxBuffer has %d bytes"), bytes);
   396             __PRINT1(_L("RxBuffer has %d bytes"), bytes);
   410 			FlushDataOut(bytes);
   397             FlushDataOut(bytes);
   411 			}
   398             }
   412 		}
   399         }
   413 
   400 
   414 	ClientReadCbw();
   401     ClientReadCbw();
   415 	return res;
   402     return res;
   416 	}
   403     }
   417 
   404 
   418 
   405 
   419 void CBulkOnlyTransport::HwStop()
   406 void CBulkOnlyTransport::HwStop()
   420 	{
   407     {
   421     __MSFNLOG
   408     if (iStarted)
   422 	if (iStarted)
   409         {
   423 		{
       
   424         iController.DriveManager().Disconnect();
   410         iController.DriveManager().Disconnect();
   425 		Cancel();
   411         Cancel();
   426 		iBotControlInterface->Cancel();
   412         iBotControlInterface->Cancel();
   427 		iProtocol->Cancel();
   413         iProtocol->Cancel();
   428 		iStarted = EFalse;
   414         iStarted = EFalse;
   429 		}
   415         }
   430 	}
   416     }
   431 
   417 
   432 
   418 
   433 void CBulkOnlyTransport::HwSuspend()
   419 void CBulkOnlyTransport::HwSuspend()
   434 	{
   420     {
   435     __MSFNLOG
       
   436     iController.DriveManager().Disconnect();
   421     iController.DriveManager().Disconnect();
   437 	}
   422     }
   438 
   423 
   439 
   424 
   440 void CBulkOnlyTransport::HwResume()
   425 void CBulkOnlyTransport::HwResume()
   441 	{
   426     {
   442     __MSFNLOG
       
   443     iController.DriveManager().Connect();
   427     iController.DriveManager().Connect();
   444 	}
   428     }
   445 
   429 
   446 
   430 
   447 /**
   431 /**
   448 Stops the Bulk Only Transport
   432 Stops the Bulk Only Transport
   449 */
   433 */
   450 TInt CBulkOnlyTransport::Stop()
   434 TInt CBulkOnlyTransport::Stop()
   451 	{
   435     {
   452     __MSFNLOG
   436     iBotControlInterface->Cancel();
   453 	iBotControlInterface->Cancel();
   437     iDeviceStateNotifier->Cancel();
   454 	iDeviceStateNotifier->Cancel();
   438     Cancel();
   455 	Cancel();
   439     if  (iInterfaceConfigured)
   456 	if  (iInterfaceConfigured)
   440         {
   457 		{
   441         iLdd.ReleaseInterface(0);
   458 		iLdd.ReleaseInterface(0);
   442         SetupConfigurationDescriptor(ETrue);
   459 		SetupConfigurationDescriptor(ETrue);
   443         iLdd.Close();
   460 		iLdd.Close();
   444         }
   461 		}
   445     iCurrentState = ENone;
   462 	iCurrentState = ENone;
   446     iInterfaceConfigured = EFalse;
   463 	iInterfaceConfigured = EFalse;
   447 
   464 
   448     return KErrNone;
   465 	return KErrNone;
   449     }
   466 	}
       
   467 
   450 
   468 
   451 
   469 /**
   452 /**
   470 Read aLength bytes of data from the host into the read buffer.
   453 Read aLength bytes of data from the host into the read buffer.
   471 @param aLength The number of bytes to read from the host.
   454 @param aLength The number of bytes to read from the host.
   472 */
   455 */
   473 void CBulkOnlyTransport::ClientReadCbw()
   456 void CBulkOnlyTransport::ClientReadCbw()
   474 	{
   457     {
   475     __MSFNLOG
   458     if (IsActive())
   476 	if (IsActive())
   459         {
   477 		{
   460         __PRINT(_L("Still active\n"));
   478 		__PRINT(_L("Still active\n"));
   461         __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsBulkOnlyStillActive));
   479 		__ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsBulkOnlyStillActive));
   462         return;
   480 		return;
   463         }
   481 		}
       
   482 
   464 
   483     ReadCbw();
   465     ReadCbw();
   484     }
   466     }
   485 
   467 
   486 
   468 
   487 void CBulkOnlyTransport::ReadCbw()
   469 void CBulkOnlyTransport::ReadCbw()
   488 	{
   470     {
   489     __MSFNLOG
   471     iCbwBuf.SetMax();
   490 	iCbwBuf.SetMax();
   472     iLdd.ReadUntilShort(iStatus, KOutEndpoint, iCbwBuf, iCbwBuf.Length());
   491 	iLdd.ReadUntilShort(iStatus, KOutEndpoint, iCbwBuf, iCbwBuf.Length());
   473     iCurrentState = EWaitForCBW;
   492 	iCurrentState = EWaitForCBW;
   474     SetActive();
   493 	SetActive();
   475     }
   494 	}
       
   495 
   476 
   496 
   477 
   497 void CBulkOnlyTransport::DoCancel()
   478 void CBulkOnlyTransport::DoCancel()
   498 	{
   479     {
   499     __MSFNLOG
   480     iLdd.WriteCancel(KInEndpoint);
   500 	iLdd.WriteCancel(KInEndpoint);
   481     iLdd.ReadCancel(KOutEndpoint);
   501 	iLdd.ReadCancel(KOutEndpoint);
   482     }
   502 	}
       
   503 
   483 
   504 
   484 
   505 void CBulkOnlyTransport::Activate(TInt aReason)
   485 void CBulkOnlyTransport::Activate(TInt aReason)
   506     {
   486     {
   507     __MSFNLOG
       
   508     SetActive();
   487     SetActive();
   509     TRequestStatus* r = &iStatus;
   488     TRequestStatus* r = &iStatus;
   510     User::RequestComplete(r, aReason);
   489     User::RequestComplete(r, aReason);
   511     }
   490     }
   512 
   491 
   513 
   492 
   514 void CBulkOnlyTransport::RunL()
   493 void CBulkOnlyTransport::RunL()
   515 	{
   494     {
   516     __MSFNLOG
   495     if (iStatus != KErrNone)
   517 	if (iStatus != KErrNone)
   496         {
   518 		{
   497         __PRINT1(_L("Error %d in RunL, halt endpoints \n"), iStatus.Int());
   519 		__PRINT1(_L("Error %d in RunL, halt endpoints \n"), iStatus.Int());
   498         SetPermError(); //halt endpoints for reset recovery
   520 		SetPermError(); //halt endpoints for reset recovery
   499         return;
   521 		return;
   500         }
   522 		}
   501 
   523 
   502     switch (iCurrentState)
   524 	switch (iCurrentState)
   503         {
   525 		{
       
   526         case EWaitForCBW:
   504         case EWaitForCBW:
   527             __PRINT(_L("EWaitForCBW"));
   505             __PRINT(_L("EWaitForCBW"));
   528             TRAPD(err, DecodeCbwL());
   506             TRAPD(err, DecodeCbwL());
   529             if (err)
   507             if (err)
   530                 {
   508                 {
   536                 // state until a Reset Recovery." Here we keep bulk-in ep
   514                 // state until a Reset Recovery." Here we keep bulk-in ep
   537                 // stalled and ignore bulk-out ep.
   515                 // stalled and ignore bulk-out ep.
   538                 SetPermError();
   516                 SetPermError();
   539                 return;
   517                 return;
   540                 }
   518                 }
   541 			break;
   519             break;
   542 
   520 
   543         case EHandleDataIn:
   521         case EHandleDataIn:
   544             {
   522             {
   545             __PRINT(_L("EHandleDataIn"));
   523             __PRINT(_L("EHandleDataIn"));
   546             iDataTransferMan.SetModeNoData();
   524             iDataTransferMan.SetModeNoData();
   547 
   525 
   548 			if (iDataTransferMan.iDataResidue && iStallAllowed)
   526             if (iDataTransferMan.iDataResidue && iStallAllowed)
   549 				{
   527                 {
   550 				StallEndpointAndWaitForClear(KInEndpoint);
   528                 StallEndpointAndWaitForClear(KInEndpoint);
   551 				}
   529                 }
   552 #ifdef MSDC_TESTMODE
   530 #ifdef MSDC_TESTMODE
   553             if (iTestParser && iTestParser->Enabled())
   531             if (iTestParser && iTestParser->Enabled())
   554                 {
   532                 {
   555                 if (iTestParser->TestCase() == TTestParser::ETestCaseDiStallCsw)
   533                 if (iTestParser->TestCase() == TTestParser::ETestCaseDiStallCsw)
   556                     {
   534                     {
   558                     __TESTMODEPRINT1("CBW Tag=0x%x: Stalling CSW Data-In", iCbwTag);
   536                     __TESTMODEPRINT1("CBW Tag=0x%x: Stalling CSW Data-In", iCbwTag);
   559                     StallEndpointAndWaitForClear(KInEndpoint);
   537                     StallEndpointAndWaitForClear(KInEndpoint);
   560                     }
   538                     }
   561                 }
   539                 }
   562 #endif
   540 #endif
   563 			SendCsw(iCbwTag, iDataTransferMan.iDataResidue, iCmdStatus);
   541             SendCsw(iCbwTag, iDataTransferMan.iDataResidue, iCmdStatus);
   564             }
   542             }
   565 			break;
   543             break;
   566 
   544 
   567 		case EHandleDataOut:
   545         case EHandleDataOut:
   568 			{
   546             {
   569             TUint bytesWritten;
   547             TUint bytesWritten;
   570             TInt ret = iProtocol->MediaWritePacket(bytesWritten);
   548             TInt ret = iProtocol->MediaWritePacket(bytesWritten);
   571             iDataTransferMan.iDataResidue -= bytesWritten;
   549             iDataTransferMan.iDataResidue -= bytesWritten;
   572 
   550 
   573 			switch(ret)
   551             switch(ret)
   574                 {
   552                 {
   575             case KErrCompletion:
   553             case KErrCompletion:
   576                 {
   554                 {
   577                 // The protocol has indicated with KErrCompletion that
   555                 // The protocol has indicated with KErrCompletion that
   578                 // sufficient data is available in the buffer to process the
   556                 // sufficient data is available in the buffer to process the
   665                 SendCsw(iCbwTag, iDataTransferMan.iDataResidue, iCmdStatus);
   643                 SendCsw(iCbwTag, iDataTransferMan.iDataResidue, iCmdStatus);
   666                 }
   644                 }
   667                 break;  // KErrNone
   645                 break;  // KErrNone
   668                 } // switch
   646                 } // switch
   669             }
   647             }
   670 			break;  // EReadingData
   648             break;  // EReadingData
   671 
   649 
   672 		case ESendingCSW:
   650         case ESendingCSW:
   673 			__PRINT(_L("ESendingCSW"));
   651             __PRINT(_L("ESendingCSW"));
   674 			ReadCbw();
   652             ReadCbw();
   675 			break;
   653             break;
   676 
   654 
   677         case EPermErr:
   655         case EPermErr:
   678 			__PRINT(_L("EPermErr"));
   656             __PRINT(_L("EPermErr"));
   679 			StallEndpointAndWaitForClear(KInEndpoint);
   657             StallEndpointAndWaitForClear(KInEndpoint);
   680             break;
   658             break;
   681 
   659 
   682         default:
   660         default:
   683 			SetPermError();		// unexpected state
   661             SetPermError();     // unexpected state
   684 		}
   662         }
   685 	}
   663     }
   686 
   664 
   687 
   665 
   688 /**
   666 /**
   689 Decode the CBW received from the host via KOutEndpoint
   667 Decode the CBW received from the host via KOutEndpoint
   690 
   668 
   692 - Depending on the command, more data may be transmitted/received.
   670 - Depending on the command, more data may be transmitted/received.
   693 - ...or the CSW is sent (if not a data command).
   671 - ...or the CSW is sent (if not a data command).
   694 
   672 
   695 */
   673 */
   696 void CBulkOnlyTransport::DecodeCbwL()
   674 void CBulkOnlyTransport::DecodeCbwL()
   697 	{
   675     {
   698     __MSFNLOG
       
   699     TBotServerReq req;
   676     TBotServerReq req;
   700     req.DecodeL(iCbwBuf);
   677     req.DecodeL(iCbwBuf);
   701 
   678 
   702     if (!(req.IsValidCbw() && req.IsMeaningfulCbw(iMaxLun)))
   679     if (!(req.IsValidCbw() && req.IsMeaningfulCbw(iMaxLun)))
   703         {
   680         {
   704         User::Leave(KErrGeneral);
   681         User::Leave(KErrGeneral);
   705         }
   682         }
   706 
   683 
   707     TPtrC8 aData(&iCbwBuf[TBotCbw::KCbwCbOffset], TBotCbw::KMaxCbwcbLength);
   684     TPtrC8 aData(&iCbwBuf[TBotCbw::KCbwCbOffset], TBotCbw::KMaxCbwcbLength);
   708 	//aData.Set(&iCbwBuf[TBotCbw::KCbwCbOffset], TBotCbw::KMaxCbwcbLength);
   685     //aData.Set(&iCbwBuf[TBotCbw::KCbwCbOffset], TBotCbw::KMaxCbwcbLength);
   709     TUint8 lun = req.Lun();
   686     TUint8 lun = req.Lun();
   710 
   687 
   711     iCbwTag  = 	req.Tag();
   688     iCbwTag  =  req.Tag();
   712     TUint32 hostDataLength = req.DataTransferLength();
   689     TUint32 hostDataLength = req.DataTransferLength();
   713     iDataTransferMan.SetHostDataLen(hostDataLength);
   690     iDataTransferMan.SetHostDataLen(hostDataLength);
   714 
   691 
   715     TBotServerReq::TCbwDirection dataToHost = req.Direction();
   692     TBotServerReq::TCbwDirection dataToHost = req.Direction();
   716 
   693 
   717     __PRINT4(_L("lun =%d, hostDataLength=%d, CBWtag = 0x%X\n, dataToHost=%d\n"),
   694     __PRINT4(_L("lun =%d, hostDataLength=%d, CBWtag = 0x%X\n, dataToHost=%d\n"),
   718              lun, hostDataLength, iCbwTag, dataToHost);
   695              lun, hostDataLength, iCbwTag, dataToHost);
   719 
   696 
   720 	//////////////////////////////////////////////
   697     //////////////////////////////////////////////
   721 	TBool ret = iProtocol->DecodePacket(aData, lun);
   698     TBool ret = iProtocol->DecodePacket(aData, lun);
   722 	//////////////////////////////////////////////
   699     //////////////////////////////////////////////
   723 
   700 
   724 	iStallAllowed = ETrue;
   701     iStallAllowed = ETrue;
   725 
   702 
   726 	if (!ret)
   703     if (!ret)
   727 		{
   704         {
   728 		__PRINT(_L("Command Failed\n"));
   705         __PRINT(_L("Command Failed\n"));
   729 		iCmdStatus = TBotCsw::ECommandFailed;
   706         iCmdStatus = TBotCsw::ECommandFailed;
   730 		}
   707         }
   731 	else
   708     else
   732 		{
   709         {
   733 		__PRINT(_L("Command Passed\n"));
   710         __PRINT(_L("Command Passed\n"));
   734 		iCmdStatus = TBotCsw::ECommandPassed;
   711         iCmdStatus = TBotCsw::ECommandPassed;
   735 		}
   712         }
   736 
   713 
   737 	if (hostDataLength)    // Host expected data transfer
   714     if (hostDataLength)    // Host expected data transfer
   738 		{
   715         {
   739 		if (dataToHost == TBotServerReq::EDataIn)  // send data to host
   716         if (dataToHost == TBotServerReq::EDataIn)  // send data to host
   740 			{
   717             {
   741             if (!iDataTransferMan.IsModeDataIn())
   718             if (!iDataTransferMan.IsModeDataIn())
   742 				{
   719                 {
   743 				__PRINT(_L("Write buffer was not setup\n"));
   720                 __PRINT(_L("Write buffer was not setup\n"));
   744 
   721 
   745 				if (hostDataLength <= KBOTMaxBufSize)
   722                 if (hostDataLength <= KBOTMaxBufSize)
   746 					{
   723                     {
   747 					// Case 4 or 8"
   724                     // Case 4 or 8"
   748 					iBuf.FillZ(hostDataLength);
   725                     iBuf.FillZ(hostDataLength);
   749 					iLdd.Write(iStatus, KInEndpoint, iBuf, hostDataLength);
   726                     iLdd.Write(iStatus, KInEndpoint, iBuf, hostDataLength);
   750 					SetActive();
   727                     SetActive();
   751 					iCurrentState = EHandleDataIn;
   728                     iCurrentState = EHandleDataIn;
   752 					iStallAllowed = EFalse;
   729                     iStallAllowed = EFalse;
   753 					if (iDataTransferMan.IsModeDataOut())
   730                     if (iDataTransferMan.IsModeDataOut())
   754 						{
   731                         {
   755                         //read buffer WAS set up - case (8)
   732                         //read buffer WAS set up - case (8)
   756 						iCmdStatus = TBotCsw::EPhaseError;
   733                         iCmdStatus = TBotCsw::EPhaseError;
   757 						}
   734                         }
   758 					return;
   735                     return;
   759 					}
   736                     }
   760 				else
   737                 else
   761 					{
   738                     {
   762                     // Use next block instead of StallEndpointAndWaitForClear(KInEndpoint);
   739                     // Use next block instead of StallEndpointAndWaitForClear(KInEndpoint);
   763                     FlushDataIn(hostDataLength);
   740                     FlushDataIn(hostDataLength);
   764 					}
   741                     }
   765 
   742 
   766 				if (iDataTransferMan.IsModeDataOut())
   743                 if (iDataTransferMan.IsModeDataOut())
   767 					{
   744                     {
   768                     //read buffer WAS set up - case (8)
   745                     //read buffer WAS set up - case (8)
   769 					SendCsw(iCbwTag, hostDataLength, TBotCsw::EPhaseError);
   746                     SendCsw(iCbwTag, hostDataLength, TBotCsw::EPhaseError);
   770 					//don't care to reset any flag - should get reset recovery
   747                     //don't care to reset any flag - should get reset recovery
   771 					}
   748                     }
   772 				else
   749                 else
   773 					{
   750                     {
   774                     // case (4)
   751                     // case (4)
   775 					SendCsw(iCbwTag, hostDataLength, iCmdStatus);
   752                     SendCsw(iCbwTag, hostDataLength, iCmdStatus);
   776 					}
   753                     }
   777 				return;
   754                 return;
   778 				}
   755                 }
   779 
   756 
   780 //==================
   757 //==================
   781 			TInt deviceDataLength = iDataTransferMan.iWriteBuf.Length();
   758             TInt deviceDataLength = iDataTransferMan.iWriteBuf.Length();
   782             iDataTransferMan.iDataResidue = hostDataLength - deviceDataLength;
   759             iDataTransferMan.iDataResidue = hostDataLength - deviceDataLength;
   783 
   760 
   784 #ifdef MSDC_TESTMODE
   761 #ifdef MSDC_TESTMODE
   785             if (iTestParser && iTestParser->Enabled())
   762             if (iTestParser && iTestParser->Enabled())
   786                 {
   763                 {
   821                                          iCbwTag, hostDataLength, deviceDataLength, residue);
   798                                          iCbwTag, hostDataLength, deviceDataLength, residue);
   822                         }
   799                         }
   823                     }
   800                     }
   824                 }
   801                 }
   825 #endif
   802 #endif
   826 			if (deviceDataLength < hostDataLength && hostDataLength <= KBOTMaxBufSize)
   803             if (deviceDataLength < hostDataLength && hostDataLength <= KBOTMaxBufSize)
   827 				{
   804                 {
   828                 // do not pad
   805                 // do not pad
   829                 // iStallAllowed = ETrue;
   806                 // iStallAllowed = ETrue;
   830                 // __PRINT1(_L("iBuf.Length=%d\n"),iBuf.Length());
   807                 // __PRINT1(_L("iBuf.Length=%d\n"),iBuf.Length());
   831                 // iLdd.Write(iStatus, KInEndpoint, iBuf, deviceDataLength);
   808                 // iLdd.Write(iStatus, KInEndpoint, iBuf, deviceDataLength);
   832                 // SetActive();
   809                 // SetActive();
   840                 __PRINT1(_L("iBuf.Length=%d\n"),iBuf.Length());
   817                 __PRINT1(_L("iBuf.Length=%d\n"),iBuf.Length());
   841                 iLdd.Write(iStatus, KInEndpoint, iBuf, hostDataLength);
   818                 iLdd.Write(iStatus, KInEndpoint, iBuf, hostDataLength);
   842                 SetActive();
   819                 SetActive();
   843                 iCurrentState = EHandleDataIn;
   820                 iCurrentState = EHandleDataIn;
   844 
   821 
   845 				return;
   822                 return;
   846 				}
   823                 }
   847 
   824 
   848 			if (deviceDataLength == hostDataLength)
   825             if (deviceDataLength == hostDataLength)
   849 				{
   826                 {
   850                 //case (6)[==]
   827                 //case (6)[==]
   851 #ifdef MSDC_TESTMODE
   828 #ifdef MSDC_TESTMODE
   852                 if (iTestParser && iTestParser->Enabled())
   829                 if (iTestParser && iTestParser->Enabled())
   853                     {
   830                     {
   854                     if (iTestParser->TestCase() == TTestParser::ETestCaseDiStallData)
   831                     if (iTestParser->TestCase() == TTestParser::ETestCaseDiStallData)
   858                         StallEndpointAndWaitForClear(KInEndpoint);
   835                         StallEndpointAndWaitForClear(KInEndpoint);
   859                         }
   836                         }
   860                     }
   837                     }
   861 #endif
   838 #endif
   862 
   839 
   863 				DataInWriteRequest(deviceDataLength);
   840                 DataInWriteRequest(deviceDataLength);
   864 				return;
   841                 return;
   865 				}
   842                 }
   866 			else if (deviceDataLength < hostDataLength)
   843             else if (deviceDataLength < hostDataLength)
   867 				{
   844                 {
   868                 //case (5)[<]
   845                 //case (5)[<]
   869 				DataInWriteRequest(deviceDataLength, ETrue);		// Send ZLP
   846                 DataInWriteRequest(deviceDataLength, ETrue);        // Send ZLP
   870 				return;
   847                 return;
   871 				}
   848                 }
   872 			else
   849             else
   873 				{
   850                 {
   874                 // deviceDataLength > hostDataLength - case (7)
   851                 // deviceDataLength > hostDataLength - case (7)
   875 				iCmdStatus = TBotCsw::EPhaseError;
   852                 iCmdStatus = TBotCsw::EPhaseError;
   876 				iDataTransferMan.iDataResidue = 0;
   853                 iDataTransferMan.iDataResidue = 0;
   877 				DataInWriteRequest(hostDataLength);
   854                 DataInWriteRequest(hostDataLength);
   878 				return;
   855                 return;
   879 				}
   856                 }
   880 			}
   857             }
   881 		else  // read data from host
   858         else  // read data from host
   882 			{
   859             {
   883 			if (!iDataTransferMan.IsModeDataOut())
   860             if (!iDataTransferMan.IsModeDataOut())
   884 				{
   861                 {
   885 				__PRINT(_L("Read buffer was not setup\n"));
   862                 __PRINT(_L("Read buffer was not setup\n"));
   886 
   863 
   887                 // Use next block instead of StallEndpointAndWaitForClear(KOutEndpoint);
   864                 // Use next block instead of StallEndpointAndWaitForClear(KOutEndpoint);
   888                 FlushDataOut(hostDataLength);
   865                 FlushDataOut(hostDataLength);
   889 				if (iDataTransferMan.IsModeDataIn())
   866                 if (iDataTransferMan.IsModeDataIn())
   890 					{
   867                     {
   891                     //case (10)
   868                     //case (10)
   892 					SendCsw(iCbwTag, hostDataLength, TBotCsw::EPhaseError);
   869                     SendCsw(iCbwTag, hostDataLength, TBotCsw::EPhaseError);
   893 					}
   870                     }
   894 				else
   871                 else
   895 					{
   872                     {
   896                     // case (9)
   873                     // case (9)
   897 					SendCsw(iCbwTag, hostDataLength, iCmdStatus);
   874                     SendCsw(iCbwTag, hostDataLength, iCmdStatus);
   898 					}
   875                     }
   899 				return;
   876                 return;
   900 				}
   877                 }
   901 
   878 
   902 			TInt deviceDataLength = iDataTransferMan.iReadBuf.Length();
   879             TInt deviceDataLength = iDataTransferMan.iReadBuf.Length();
   903 
   880 
   904 			if (deviceDataLength <= hostDataLength)
   881             if (deviceDataLength <= hostDataLength)
   905 				{
   882                 {
   906                 // case (11) and (12)
   883                 // case (11) and (12)
   907 #ifdef MSDC_TESTMODE
   884 #ifdef MSDC_TESTMODE
   908                 TBool done = EFalse;
   885                 TBool done = EFalse;
   909                 if (iTestParser && iTestParser->Enabled())
   886                 if (iTestParser && iTestParser->Enabled())
   910                     {
   887                     {
   926                 if (!done)
   903                 if (!done)
   927                     {
   904                     {
   928                     DataOutReadRequest(deviceDataLength);
   905                     DataOutReadRequest(deviceDataLength);
   929                     }
   906                     }
   930 #else
   907 #else
   931 				DataOutReadRequest(deviceDataLength);
   908                 DataOutReadRequest(deviceDataLength);
   932 #endif
   909 #endif
   933 				return;
   910                 return;
   934 				}
   911                 }
   935 			else
   912             else
   936 				{
   913                 {
   937                 // case  (13)
   914                 // case  (13)
   938                 /**
   915                 /**
   939                  * Comment following line in order to pass compliant test.
   916                  * Comment following line in order to pass compliant test.
   940                  * As spec said in case 13:"The device may receive data up to a
   917                  * As spec said in case 13:"The device may receive data up to a
   941                  * total of dCBWDataTransferLength."
   918                  * total of dCBWDataTransferLength."
   942                  * Here we choose to ignore incoming data.
   919                  * Here we choose to ignore incoming data.
   943                  */
   920                  */
   944 				//StallEndpointAndWaitForClear(KOutEndpoint); //Stall Out endpoint
   921                 //StallEndpointAndWaitForClear(KOutEndpoint); //Stall Out endpoint
   945                 if (iDataTransferMan.IsModeDataOut())
   922                 if (iDataTransferMan.IsModeDataOut())
   946                     {
   923                     {
   947                     iDataTransferMan.SetModeNoData();
   924                     iDataTransferMan.SetModeNoData();
   948                     iLdd.Read(iStatus, KOutEndpoint, iDataTransferMan.iReadBuf, hostDataLength);
   925                     iLdd.Read(iStatus, KOutEndpoint, iDataTransferMan.iReadBuf, hostDataLength);
   949                     User::WaitForRequest(iStatus);
   926                     User::WaitForRequest(iStatus);
   950                     iProtocol->MediaWriteAbort();
   927                     iProtocol->MediaWriteAbort();
   951                     }
   928                     }
   952                 SendCsw(iCbwTag, hostDataLength, TBotCsw::EPhaseError);
   929                 SendCsw(iCbwTag, hostDataLength, TBotCsw::EPhaseError);
   953 				return;
   930                 return;
   954 				}
   931                 }
   955 			}
   932             }
   956 		}
   933         }
   957 	else  // Host expected no data transfer
   934     else  // Host expected no data transfer
   958 		{
   935         {
   959 		__PRINT(_L("No data transfer expected\n"));
   936         __PRINT(_L("No data transfer expected\n"));
   960 		iDataTransferMan.iDataResidue = 0;
   937         iDataTransferMan.iDataResidue = 0;
   961 		if (!iDataTransferMan.IsModeNoData())
   938         if (!iDataTransferMan.IsModeNoData())
   962 			{
   939             {
   963             // case (2) and (3)
   940             // case (2) and (3)
   964 			SendCsw(iCbwTag, 0, TBotCsw::EPhaseError);
   941             SendCsw(iCbwTag, 0, TBotCsw::EPhaseError);
   965 			}
   942             }
   966 		else
   943         else
   967 			{
   944             {
   968             //case (1)
   945             //case (1)
   969 #ifdef MSDC_TESTMODE
   946 #ifdef MSDC_TESTMODE
   970             if (iTestParser && iTestParser->Enabled())
   947             if (iTestParser && iTestParser->Enabled())
   971                 {
   948                 {
   972                 TInt testCase = iTestParser->TestCase();
   949                 TInt testCase = iTestParser->TestCase();
   982                     __TESTMODEPRINT1("CBW Tag=0x%x: Enabling phase error (no data)", iCbwTag);
   959                     __TESTMODEPRINT1("CBW Tag=0x%x: Enabling phase error (no data)", iCbwTag);
   983                     iTestParser->SetPhaseError();
   960                     iTestParser->SetPhaseError();
   984                     }
   961                     }
   985                 }
   962                 }
   986 #endif
   963 #endif
   987 			SendCsw(iCbwTag, 0, iCmdStatus);
   964             SendCsw(iCbwTag, 0, iCmdStatus);
   988 			}
   965             }
   989 		}
   966         }
   990 	}
   967     }
   991 
   968 
   992 
   969 
   993 /**
   970 /**
   994 Initiate stalling of bulk IN endpoint.
   971 Initiate stalling of bulk IN endpoint.
   995 Used when protocol wants to force host to initiate a reset recovery.
   972 Used when protocol wants to force host to initiate a reset recovery.
   996 */
   973 */
   997 void CBulkOnlyTransport::SetPermError()
   974 void CBulkOnlyTransport::SetPermError()
   998 	{
   975     {
   999     __MSFNLOG
       
  1000     iCurrentState = EPermErr;
   976     iCurrentState = EPermErr;
  1001     Activate(KErrNone);
   977     Activate(KErrNone);
  1002 	}
   978     }
  1003 
   979 
  1004 
   980 
  1005 /**
   981 /**
  1006 Send data provided by protocol to the host
   982 Send data provided by protocol to the host
  1007 
   983 
  1008 @param aLength amount of data (in bytes) to be send to host
   984 @param aLength amount of data (in bytes) to be send to host
  1009 */
   985 */
  1010 void CBulkOnlyTransport::DataInWriteRequest(TUint aLength, TBool aZlpRequired)
   986 void CBulkOnlyTransport::DataInWriteRequest(TUint aLength, TBool aZlpRequired)
  1011 	{
   987     {
  1012     __MSFNLOG
   988     iLdd.Write(iStatus, KInEndpoint, iDataTransferMan.iWriteBuf, aLength, aZlpRequired);
  1013 	iLdd.Write(iStatus, KInEndpoint, iDataTransferMan.iWriteBuf, aLength, aZlpRequired);
       
  1014     iDataTransferMan.iTransportResidue -= aLength;
   989     iDataTransferMan.iTransportResidue -= aLength;
  1015 	iCurrentState = EHandleDataIn;
   990     iCurrentState = EHandleDataIn;
  1016 	SetActive();
   991     SetActive();
  1017 	}
   992     }
  1018 
   993 
  1019 
   994 
  1020 /**
   995 /**
  1021 Request data form the host for the protocol
   996 Request data form the host for the protocol
  1022 
   997 
  1023 @param aLength amount of data (in bytes) to be received from the host
   998 @param aLength amount of data (in bytes) to be received from the host
  1024 */
   999 */
  1025 void CBulkOnlyTransport::DataOutReadRequest(TUint aLength)
  1000 void CBulkOnlyTransport::DataOutReadRequest(TUint aLength)
  1026 	{
  1001     {
  1027     __MSFNLOG
  1002     iLdd.Read(iStatus, KOutEndpoint, iDataTransferMan.iReadBuf, aLength);
  1028 	iLdd.Read(iStatus, KOutEndpoint, iDataTransferMan.iReadBuf, aLength);
  1003     iDataTransferMan.iTransportResidue -= aLength;
  1029 	iDataTransferMan.iTransportResidue -= aLength;
  1004     iCurrentState = EHandleDataOut;
  1030 	iCurrentState = EHandleDataOut;
       
  1031     SetActive();
  1005     SetActive();
  1032 	}
  1006     }
  1033 
  1007 
  1034 
  1008 
  1035 /**
  1009 /**
  1036 Send Command Status Wrapper to the host
  1010 Send Command Status Wrapper to the host
  1037 
  1011 
  1039 @param aDataResidue the difference between the amount of data expected by the
  1013 @param aDataResidue the difference between the amount of data expected by the
  1040        host, and the actual amount of data processed by the device.
  1014        host, and the actual amount of data processed by the device.
  1041 @param aStatus indicates the success or failure of the command.
  1015 @param aStatus indicates the success or failure of the command.
  1042 */
  1016 */
  1043 void CBulkOnlyTransport::SendCsw(TUint aTag, TUint32 aDataResidue, TBotCsw::TCswStatus aStatus)
  1017 void CBulkOnlyTransport::SendCsw(TUint aTag, TUint32 aDataResidue, TBotCsw::TCswStatus aStatus)
  1044 	{
  1018     {
  1045     __MSFNLOG
  1019     __PRINT2(_L("DataResidue = %d, Status = %d \n"), aDataResidue, aStatus);
  1046 	__PRINT2(_L("DataResidue = %d, Status = %d \n"), aDataResidue, aStatus);
       
  1047     iCsw.SetLength(TBotCsw::KCswLength);
  1020     iCsw.SetLength(TBotCsw::KCswLength);
  1048     TBotServerResp resp(iCbwTag, aDataResidue, aStatus);
  1021     TBotServerResp resp(iCbwTag, aDataResidue, aStatus);
  1049 #ifdef MSDC_TESTMODE
  1022 #ifdef MSDC_TESTMODE
  1050     resp.EncodeL(iCsw, iTestParser);
  1023     resp.EncodeL(iCsw, iTestParser);
  1051 #else
  1024 #else
  1052     resp.EncodeL(iCsw);
  1025     resp.EncodeL(iCsw);
  1053 #endif
  1026 #endif
  1054 	iLdd.Write(iStatus, KInEndpoint, iCsw, TBotCsw::KCswLength);
  1027     iLdd.Write(iStatus, KInEndpoint, iCsw, TBotCsw::KCswLength);
  1055 	iCurrentState = ESendingCSW;
  1028     iCurrentState = ESendingCSW;
  1056 	SetActive();
  1029     SetActive();
  1057 	}
  1030     }
  1058 
  1031 
  1059 
  1032 
  1060 /**
  1033 /**
  1061 Associates the transport with the protocol.  Called during initialization of the controller.
  1034 Associates the transport with the protocol.  Called during initialization of the controller.
  1062 
  1035 
  1063 @param aProtocol reference to the protocol
  1036 @param aProtocol reference to the protocol
  1064 */
  1037 */
  1065 void CBulkOnlyTransport::RegisterProtocol(MServerProtocol& aProtocol)
  1038 void CBulkOnlyTransport::RegisterProtocol(MServerProtocol& aProtocol)
  1066 	{
  1039     {
  1067     __MSFNLOG
  1040     iProtocol = &aProtocol;
  1068 	iProtocol = &aProtocol;
  1041     }
  1069 	}
       
  1070 
  1042 
  1071 
  1043 
  1072 /**
  1044 /**
  1073 Used by CControlInterface
  1045 Used by CControlInterface
  1074 
  1046 
  1075 @return reference to the controller which instantiate the CBulkOnlyTransport
  1047 @return reference to the controller which instantiate the CBulkOnlyTransport
  1076 */
  1048 */
  1077 CUsbMassStorageController& CBulkOnlyTransport::Controller()
  1049 CUsbMassStorageController& CBulkOnlyTransport::Controller()
  1078 	{
  1050     {
  1079 	return iController;
  1051     return iController;
  1080 	}
  1052     }
  1081 
  1053 
  1082 
  1054 
  1083 /**
  1055 /**
  1084 @return the number of logical units supported by the device.
  1056 @return the number of logical units supported by the device.
  1085 Logical Unit Numbers on the device shall be numbered contiguously starting from LUN
  1057 Logical Unit Numbers on the device shall be numbered contiguously starting from LUN
  1086 0 to a maximum LUN of 15 (Fh).
  1058 0 to a maximum LUN of 15 (Fh).
  1087 */
  1059 */
  1088 TInt CBulkOnlyTransport::MaxLun()
  1060 TInt CBulkOnlyTransport::MaxLun()
  1089 	{
  1061     {
  1090     __MSFNLOG
  1062     return iMaxLun;
  1091 	return iMaxLun;
  1063     }
  1092 	}
       
  1093 
  1064 
  1094 
  1065 
  1095 /**
  1066 /**
  1096 Used by CControlInterface
  1067 Used by CControlInterface
  1097 @return reference to USB logical driver
  1068 @return reference to USB logical driver
  1098 */
  1069 */
  1099 RDevUsbcClient& CBulkOnlyTransport::Ldd()
  1070 RDevUsbcClient& CBulkOnlyTransport::Ldd()
  1100 	{
  1071     {
  1101 	return iLdd;
  1072     return iLdd;
  1102 	}
  1073     }
  1103 
  1074 
  1104 
  1075 
  1105 void CBulkOnlyTransport::StallEndpointAndWaitForClear(TEndpointNumber aEndpoint)
  1076 void CBulkOnlyTransport::StallEndpointAndWaitForClear(TEndpointNumber aEndpoint)
  1106 	{
  1077     {
  1107     __MSFNLOG
  1078     __ASSERT_DEBUG(aEndpoint != EEndpoint0, User::Panic(KUsbMsClientPanicCat, EMsWrongEndpoint));
  1108 	__ASSERT_DEBUG(aEndpoint != EEndpoint0, User::Panic(KUsbMsClientPanicCat, EMsWrongEndpoint));
  1079 
  1109 
  1080     // Now stall this endpoint
  1110 	// Now stall this endpoint
  1081     __PRINT1(_L("Stalling endpoint %d"), aEndpoint);
  1111 	__PRINT1(_L("Stalling endpoint %d"), aEndpoint);
  1082     __TESTMODEPRINT2("CBW Tag=0x%x: Stalling endpoint %d", iCbwTag, aEndpoint);
  1112 	__TESTMODEPRINT2("CBW Tag=0x%x: Stalling endpoint %d", iCbwTag, aEndpoint);
  1083     TInt r = iLdd.HaltEndpoint(aEndpoint);
  1113 	TInt r = iLdd.HaltEndpoint(aEndpoint);
  1084     if (r != KErrNone)
  1114 	if (r != KErrNone)
  1085         {
  1115 		{
  1086         __PRINT2(_L("Error: stalling ep %d failed: %d"), aEndpoint, r);
  1116 		__PRINT2(_L("Error: stalling ep %d failed: %d"), aEndpoint, r);
  1087         }
  1117 		}
  1088     TEndpointState ep_state;
  1118 	TEndpointState ep_state;
  1089     TInt i = 0;
  1119 	TInt i = 0;
  1090     do
  1120 	do
  1091         {
  1121 		{
  1092         // Wait for 10ms before checking the ep status
  1122 		// Wait for 10ms before checking the ep status
  1093         User::After(10000);
  1123 		User::After(10000);
       
  1124 
  1094 
  1125         if (aEndpoint == KInEndpoint)
  1095         if (aEndpoint == KInEndpoint)
  1126             {
  1096             {
  1127             // Discard BULK-OUT data
  1097             // Discard BULK-OUT data
  1128             TInt bytes;
  1098             TInt bytes;
  1136                 __PRINT1(_L("RxBuffer has %d bytes"), bytes);
  1106                 __PRINT1(_L("RxBuffer has %d bytes"), bytes);
  1137                 FlushDataOut(bytes);
  1107                 FlushDataOut(bytes);
  1138                 }
  1108                 }
  1139             }
  1109             }
  1140 
  1110 
  1141 		iLdd.EndpointStatus(aEndpoint, ep_state);
  1111         iLdd.EndpointStatus(aEndpoint, ep_state);
  1142 		if (++i >= 550)
  1112         if (++i >= 550)
  1143 			{
  1113             {
  1144 			// 5.5 secs should be enough (see 9.2.6.1 Request Processing Timing)
  1114             // 5.5 secs should be enough (see 9.2.6.1 Request Processing Timing)
  1145 			__PRINT1(_L("Error: Checked for ep %d de-stall for 5.5s - giving up now"), aEndpoint);
  1115             __PRINT1(_L("Error: Checked for ep %d de-stall for 5.5s - giving up now"), aEndpoint);
  1146             __TESTMODEPRINT1("Error: Checked for ep %d de-stall for 5.5s - giving up now", aEndpoint);
  1116             __TESTMODEPRINT1("Error: Checked for ep %d de-stall for 5.5s - giving up now", aEndpoint);
  1147 			// We can now only hope for a Reset Recovery
  1117             // We can now only hope for a Reset Recovery
  1148 			return;
  1118             return;
  1149 			}
  1119             }
  1150 		} while ((ep_state == EEndpointStateStalled) && iStarted);
  1120         } while ((ep_state == EEndpointStateStalled) && iStarted);
  1151 	__PRINT2(_L("Checked for ep %d de-stall: %d time(s)"), aEndpoint, i);
  1121     __PRINT2(_L("Checked for ep %d de-stall: %d time(s)"), aEndpoint, i);
  1152     __TESTMODEPRINT2("Checked for ep %d de-stall: %d time(s)", aEndpoint, i);
  1122     __TESTMODEPRINT2("Checked for ep %d de-stall: %d time(s)", aEndpoint, i);
  1153 	}
  1123     }
  1154 
  1124 
  1155 
  1125 
  1156 
  1126 
  1157 /**
  1127 /**
  1158 Called by the protocol to determine how many bytes of data are available in the read buffer.
  1128 Called by the protocol to determine how many bytes of data are available in the read buffer.
  1159 
  1129 
  1160 @return The number of bytes available in the read buffer
  1130 @return The number of bytes available in the read buffer
  1161 */
  1131 */
  1162 TInt CBulkOnlyTransport::BytesAvailable()
  1132 TInt CBulkOnlyTransport::BytesAvailable()
  1163 	{
  1133     {
  1164     __MSFNLOG
  1134     TInt bytes = 0;
  1165 	TInt bytes = 0;
  1135     TInt err = iLdd.QueryReceiveBuffer(KOutEndpoint, bytes);
  1166 	TInt err = iLdd.QueryReceiveBuffer(KOutEndpoint, bytes);
  1136     if (err != KErrNone)
  1167 	if (err != KErrNone)
  1137         bytes = 0;
  1168 		bytes = 0;
  1138     return bytes;
  1169 	return bytes;
  1139     }
  1170 	}
       
  1171 
  1140 
  1172 
  1141 
  1173 /**
  1142 /**
  1174  * Read out rest data from KOutEndpoint and discard them
  1143  * Read out rest data from KOutEndpoint and discard them
  1175  */
  1144  */
  1176 void CBulkOnlyTransport::FlushDataOut(TInt aLength)
  1145 void CBulkOnlyTransport::FlushDataOut(TInt aLength)
  1177 	{
  1146     {
  1178     __MSFNLOG
  1147     iBuf.SetMax();
  1179 	iBuf.SetMax();
  1148     TRequestStatus status;
  1180 	TRequestStatus status;
  1149     while (aLength > 0)
  1181 	while (aLength > 0)
  1150         {
  1182 		{
  1151         iLdd.ReadOneOrMore(status, KOutEndpoint, iBuf, iBuf.Length());
  1183 		iLdd.ReadOneOrMore(status, KOutEndpoint, iBuf, iBuf.Length());
  1152         User::WaitForRequest(status);
  1184 		User::WaitForRequest(status);
  1153         TInt err = status.Int();
  1185 		TInt err = status.Int();
  1154         if (err != KErrNone)
  1186 		if (err != KErrNone)
  1155             {
  1187 			{
  1156             // Bad.
  1188 			// Bad.
  1157             break;
  1189 			break;
  1158             }
  1190 			}
  1159         aLength -= iBuf.Length();
  1191 		aLength -= iBuf.Length();
  1160         }
  1192 		}
  1161     }
  1193 	}
       
  1194 
  1162 
  1195 
  1163 
  1196 void CBulkOnlyTransport::FlushDataIn(TInt aLength)
  1164 void CBulkOnlyTransport::FlushDataIn(TInt aLength)
  1197     {
  1165     {
  1198 	iBuf.SetMax();
  1166     iBuf.SetMax();
  1199 	TInt c = 0;
  1167     TInt c = 0;
  1200     TInt len;
  1168     TInt len;
  1201 	TRequestStatus status;
  1169     TRequestStatus status;
  1202 	while (c < aLength)
  1170     while (c < aLength)
  1203 		{
  1171         {
  1204         len = aLength - c;
  1172         len = aLength - c;
  1205 		if (len >  KBOTMaxBufSize)
  1173         if (len >  KBOTMaxBufSize)
  1206 			{
  1174             {
  1207 			len = KBOTMaxBufSize;
  1175             len = KBOTMaxBufSize;
  1208 			}
  1176             }
  1209 		iLdd.Write(status, KInEndpoint, iBuf, len);
  1177         iLdd.Write(status, KInEndpoint, iBuf, len);
  1210 		User::WaitForRequest(status);
  1178         User::WaitForRequest(status);
  1211 		c +=  KBOTMaxBufSize;
  1179         c +=  KBOTMaxBufSize;
  1212 		}
  1180         }
  1213     }
  1181     }
  1214 
  1182 
  1215 //
  1183 //
  1216 // --- class CActiveDeviceStateNotifier ---------------------------------------------------------
  1184 // --- class CActiveDeviceStateNotifier ---------------------------------------------------------
  1217 //
  1185 //
  1218 CActiveDeviceStateNotifier::CActiveDeviceStateNotifier(CBulkOnlyTransport& aParent)
  1186 CActiveDeviceStateNotifier::CActiveDeviceStateNotifier(CBulkOnlyTransport& aParent)
  1219 :   CActive(EPriorityStandard),
  1187 :   CActive(EPriorityStandard),
  1220 	iParent(aParent),
  1188     iParent(aParent),
  1221 	iDeviceState(EUsbcNoState),
  1189     iDeviceState(EUsbcNoState),
  1222 	iOldDeviceState(EUsbcNoState)
  1190     iOldDeviceState(EUsbcNoState)
  1223 	{
  1191     {
  1224     __MSFNLOG
  1192     }
  1225 	}
       
  1226 
  1193 
  1227 
  1194 
  1228 CActiveDeviceStateNotifier* CActiveDeviceStateNotifier::NewL(CBulkOnlyTransport& aParent)
  1195 CActiveDeviceStateNotifier* CActiveDeviceStateNotifier::NewL(CBulkOnlyTransport& aParent)
  1229 	{
  1196     {
  1230     __MSFNSLOG
  1197     CActiveDeviceStateNotifier* self = new (ELeave) CActiveDeviceStateNotifier(aParent);
  1231 	CActiveDeviceStateNotifier* self = new (ELeave) CActiveDeviceStateNotifier(aParent);
  1198     CleanupStack::PushL(self);
  1232 	CleanupStack::PushL(self);
  1199     self->ConstructL();
  1233 	self->ConstructL();
  1200     CActiveScheduler::Add(self);
  1234 	CActiveScheduler::Add(self);
  1201     CleanupStack::Pop();                                    // self
  1235 	CleanupStack::Pop();									// self
  1202     return (self);
  1236 	return (self);
  1203     }
  1237 	}
       
  1238 
  1204 
  1239 
  1205 
  1240 void CActiveDeviceStateNotifier::ConstructL()
  1206 void CActiveDeviceStateNotifier::ConstructL()
  1241 	{
  1207     {
  1242     __MSFNLOG
  1208     }
  1243 	}
       
  1244 
  1209 
  1245 
  1210 
  1246 CActiveDeviceStateNotifier::~CActiveDeviceStateNotifier()
  1211 CActiveDeviceStateNotifier::~CActiveDeviceStateNotifier()
  1247 	{
  1212     {
  1248     __MSFNLOG
  1213     Cancel();                                               // base class
  1249 	Cancel();												// base class
  1214     }
  1250 	}
       
  1251 
  1215 
  1252 
  1216 
  1253 void CActiveDeviceStateNotifier::DoCancel()
  1217 void CActiveDeviceStateNotifier::DoCancel()
  1254 /**
  1218 /**
  1255  *
  1219  *
  1256  */
  1220  */
  1257 	{
  1221     {
  1258     __MSFNLOG
  1222     iParent.Ldd().AlternateDeviceStatusNotifyCancel();
  1259 	iParent.Ldd().AlternateDeviceStatusNotifyCancel();
  1223     }
  1260 	}
       
  1261 
  1224 
  1262 
  1225 
  1263 void CActiveDeviceStateNotifier::RunL()
  1226 void CActiveDeviceStateNotifier::RunL()
  1264 /**
  1227 /**
  1265  *
  1228  *
  1266  */
  1229  */
  1267 	{
  1230     {
  1268     __MSFNLOG
  1231     // This displays the device state.
  1269 	// This displays the device state.
  1232     // In a real world program, the user could take here appropriate action (cancel a
  1270 	// In a real world program, the user could take here appropriate action (cancel a
  1233     // transfer request or whatever).
  1271 	// transfer request or whatever).
  1234     if (!(iDeviceState & KUsbAlternateSetting))
  1272 	if (!(iDeviceState & KUsbAlternateSetting))
  1235         {
  1273 		{
  1236         switch (iDeviceState)
  1274 		switch (iDeviceState)
  1237             {
  1275 			{
  1238         case EUsbcDeviceStateUndefined:
  1276 		case EUsbcDeviceStateUndefined:
  1239             __PRINT(_L("Device State notifier: Undefined\n"));
  1277 			__PRINT(_L("Device State notifier: Undefined\n"));
  1240             iParent.HwStop();
  1278 			iParent.HwStop();
  1241             break;
  1279 			break;
  1242         case EUsbcDeviceStateAttached:
  1280 		case EUsbcDeviceStateAttached:
  1243             __PRINT(_L("Device State notifier: Attached\n"));
  1281 			__PRINT(_L("Device State notifier: Attached\n"));
  1244             iParent.HwStop();
  1282 			iParent.HwStop();
  1245             break;
  1283 			break;
  1246         case EUsbcDeviceStatePowered:
  1284 		case EUsbcDeviceStatePowered:
  1247             __PRINT(_L("Device State notifier: Powered\n"));
  1285 			__PRINT(_L("Device State notifier: Powered\n"));
  1248             iParent.HwStop();
  1286 			iParent.HwStop();
  1249             break;
  1287 			break;
  1250         case EUsbcDeviceStateDefault:
  1288 		case EUsbcDeviceStateDefault:
  1251             __PRINT(_L("Device State notifier: Default\n"));
  1289 			__PRINT(_L("Device State notifier: Default\n"));
  1252             iParent.HwStop();
  1290 			iParent.HwStop();
  1253             break;
  1291 			break;
  1254         case EUsbcDeviceStateAddress:
  1292 		case EUsbcDeviceStateAddress:
  1255             __PRINT(_L("Device State notifier: Address\n"));
  1293 			__PRINT(_L("Device State notifier: Address\n"));
  1256             iParent.HwStop();
  1294 			iParent.HwStop();
  1257             break;
  1295 			break;
  1258         case EUsbcDeviceStateConfigured:
  1296 		case EUsbcDeviceStateConfigured:
  1259             __PRINT(_L("Device State notifier: Configured\n"));
  1297 			__PRINT(_L("Device State notifier: Configured\n"));
  1260             if (iOldDeviceState == EUsbcDeviceStateSuspended)
  1298 			if (iOldDeviceState == EUsbcDeviceStateSuspended)
  1261                 {
  1299 				{
  1262                 iParent.HwResume();
  1300 				iParent.HwResume();
  1263                 }
  1301 				}
  1264             else
  1302 			else
  1265                 {
  1303 				{
  1266                 iParent.HwStart();
  1304 				iParent.HwStart();
  1267                 }
  1305 				}
  1268             break;
  1306 			break;
  1269         case EUsbcDeviceStateSuspended:
  1307 		case EUsbcDeviceStateSuspended:
  1270             __PRINT(_L("Device State notifier: Suspended\n"));
  1308 			__PRINT(_L("Device State notifier: Suspended\n"));
  1271             if (iOldDeviceState == EUsbcDeviceStateConfigured)
  1309 			if (iOldDeviceState == EUsbcDeviceStateConfigured)
  1272                 {
  1310 				{
  1273                 iParent.HwSuspend();
  1311 				iParent.HwSuspend();
  1274                 }
  1312 				}
  1275             break;
  1313 			break;
  1276         default:
  1314 		default:
  1277             __PRINT(_L("Device State notifier: ***BAD***\n"));
  1315 			__PRINT(_L("Device State notifier: ***BAD***\n"));
  1278             iParent.HwStop();
  1316 			iParent.HwStop();
  1279             break;
  1317 			break;
  1280             }
  1318 			}
  1281         iOldDeviceState = iDeviceState;
  1319 		iOldDeviceState = iDeviceState;
  1282         }
  1320 		}
  1283     else if (iDeviceState & KUsbAlternateSetting)
  1321 	else if (iDeviceState & KUsbAlternateSetting)
  1284         {
  1322 		{
  1285         __PRINT1(_L("Device State notifier: Alternate interface setting has changed: now %d\n"), iDeviceState & ~KUsbAlternateSetting);
  1323 		__PRINT1(_L("Device State notifier: Alternate interface setting has changed: now %d\n"), iDeviceState & ~KUsbAlternateSetting);
  1286         }
  1324 		}
  1287     Activate();
  1325 	Activate();
  1288     }
  1326 	}
       
  1327 
  1289 
  1328 
  1290 
  1329 void CActiveDeviceStateNotifier::Activate()
  1291 void CActiveDeviceStateNotifier::Activate()
  1330 /**
  1292 /**
  1331  *
  1293  *
  1332  */
  1294  */
  1333 	{
  1295     {
  1334     __MSFNLOG
  1296     if (IsActive())
  1335 	if (IsActive())
  1297         {
  1336 		{
  1298         __PRINT(_L("Still active\n"));
  1337 		__PRINT(_L("Still active\n"));
  1299         return;
  1338 		return;
  1300         }
  1339 		}
  1301     iParent.Ldd().AlternateDeviceStatusNotify(iStatus, iDeviceState);
  1340 	iParent.Ldd().AlternateDeviceStatusNotify(iStatus, iDeviceState);
  1302     SetActive();
  1341 	SetActive();
  1303     }
  1342 	}