kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/protocol/cscsiserverprotocol.cpp
changeset 297 b2826f67641f
parent 0 a41df078684a
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".
    29 #include "mdevicetransport.h"
    29 #include "mdevicetransport.h"
    30 
    30 
    31 #include "testman.h"
    31 #include "testman.h"
    32 #include "cscsiserverprotocol.h"
    32 #include "cscsiserverprotocol.h"
    33 #include "debug.h"
    33 #include "debug.h"
    34 #include "msdebug.h"
       
    35 
    34 
    36 
    35 
    37 TMediaWriteMan::TMediaWriteMan()
    36 TMediaWriteMan::TMediaWriteMan()
    38 :   iActive(EFalse),
    37 :   iActive(EFalse),
    39     iOffset(0),
    38     iOffset(0),
    40 	iMediaWriteSize(KDefaultMediaWriteSize)
    39     iMediaWriteSize(KDefaultMediaWriteSize)
    41     {
    40     {
    42     }
    41     }
    43 
    42 
    44 void TMediaWriteMan::ReportHighSpeedDevice()
    43 void TMediaWriteMan::ReportHighSpeedDevice()
    45 	{
    44     {
    46     __MSFNLOG
    45     iMediaWriteSize = KHsMediaWriteSize;
    47 	iMediaWriteSize = KHsMediaWriteSize;
    46     __PRINT1(_L("HS Device reported: SCSI will use %d bytes disk write size"), iMediaWriteSize);
    48 	__PRINT1(_L("HS Device reported: SCSI will use %d bytes disk write size"), iMediaWriteSize);
    47     }
    49 	}
       
    50 
    48 
    51 
    49 
    52 TInt64 TMediaWriteMan::Start(TUint32 aLba, TUint32 aLength, TUint32 aBlockSize)
    50 TInt64 TMediaWriteMan::Start(TUint32 aLba, TUint32 aLength, TUint32 aBlockSize)
    53     {
    51     {
    54     iActive = ETrue;
    52     iActive = ETrue;
    55     iOffset = static_cast<TInt64>(aLba) * aBlockSize;
    53     iOffset = static_cast<TInt64>(aLba) * aBlockSize;
    56     iBytesRemain = aLength * aBlockSize;
    54     iBytesRemain = aLength * aBlockSize;
    57 
    55 
    58 	TInt64 theEnd = iOffset + iBytesRemain;
    56     TInt64 theEnd = iOffset + iBytesRemain;
    59     return theEnd;
    57     return theEnd;
    60     }
    58     }
    61 
    59 
    62 TUint32 TMediaWriteMan::NextPacket()
    60 TUint32 TMediaWriteMan::NextPacket()
    63     {
    61     {
    79     }
    77     }
    80 
    78 
    81 TUint32 TMediaWriteMan::GetPacketLength() const
    79 TUint32 TMediaWriteMan::GetPacketLength() const
    82     {
    80     {
    83     // KMaxBufSize or the MediaWriteSize, whichever is smallest.
    81     // KMaxBufSize or the MediaWriteSize, whichever is smallest.
    84 	TUint32 thisLength = (iBytesRemain > KMaxBufSize) ? KMaxBufSize : iBytesRemain;
    82     TUint32 thisLength = (iBytesRemain > KMaxBufSize) ? KMaxBufSize : iBytesRemain;
    85 	thisLength = (thisLength > iMediaWriteSize) ? iMediaWriteSize : thisLength;
    83     thisLength = (thisLength > iMediaWriteSize) ? iMediaWriteSize : thisLength;
    86     return thisLength;
    84     return thisLength;
    87     }
    85     }
    88 
    86 
    89 
    87 
    90 /**
    88 /**
    91 Creates the CScsiProtocol object.  Called during controller initialisation.
    89 Creates the CScsiProtocol object.  Called during controller initialisation.
    92 
    90 
    93 @param aDriveManager reference to the drive manager object
    91 @param aDriveManager reference to the drive manager object
    94 */
    92 */
    95 CScsiServerProtocol* CScsiServerProtocol::NewL(CDriveManager& aDriveManager)
    93 CScsiServerProtocol* CScsiServerProtocol::NewL(CDriveManager& aDriveManager)
    96 	{
    94     {
    97     __MSFNSLOG
    95     CScsiServerProtocol* self = new (ELeave) CScsiServerProtocol(aDriveManager);
    98 	CScsiServerProtocol* self = new (ELeave) CScsiServerProtocol(aDriveManager);
    96     CleanupStack::PushL(self);
    99 	CleanupStack::PushL(self);
    97     self->ConstructL();
   100 	self->ConstructL();
    98     CleanupStack::Pop();
   101 	CleanupStack::Pop();
    99     return self;
   102 	return self;
   100     }
   103 	}
       
   104 
   101 
   105 #ifdef MSDC_TESTMODE
   102 #ifdef MSDC_TESTMODE
   106 CScsiServerProtocol* CScsiServerProtocol::NewL(CDriveManager& aDriveManager, TTestParser* aTestParser)
   103 CScsiServerProtocol* CScsiServerProtocol::NewL(CDriveManager& aDriveManager, TTestParser* aTestParser)
   107 	{
   104     {
   108     __MSFNSLOG
   105     CScsiServerProtocol* self = new (ELeave) CScsiServerProtocol(aDriveManager, aTestParser);
   109 	CScsiServerProtocol* self = new (ELeave) CScsiServerProtocol(aDriveManager, aTestParser);
   106     CleanupStack::PushL(self);
   110 	CleanupStack::PushL(self);
   107     self->ConstructL();
   111 	self->ConstructL();
   108     CleanupStack::Pop();
   112 	CleanupStack::Pop();
   109     return self;
   113 	return self;
   110     }
   114 	}
       
   115 #endif
   111 #endif
   116 
   112 
   117 
   113 
   118 /**
   114 /**
   119 c'tor
   115 c'tor
   120 
   116 
   121 @param aDriveManager reference to the drive manager object
   117 @param aDriveManager reference to the drive manager object
   122 */
   118 */
   123 CScsiServerProtocol::CScsiServerProtocol(CDriveManager& aDriveManager)
   119 CScsiServerProtocol::CScsiServerProtocol(CDriveManager& aDriveManager)
   124 :   iDriveManager(aDriveManager)
   120 :   iDriveManager(aDriveManager)
   125 	{
   121     {
   126     __MSFNLOG
   122     iWriteTransferPublisher = CUsbWriteTransferPublisher::NewL(iBytesWritten);
   127 
   123     iReadTransferPublisher = CUsbReadTransferPublisher::NewL(iBytesRead);
   128 	iWriteTransferPublisher = CUsbWriteTransferPublisher::NewL(iBytesWritten);
   124 
   129 	iReadTransferPublisher = CUsbReadTransferPublisher::NewL(iBytesRead);
   125     for (TUint i = 0; i < KUsbMsMaxDrives; i++)
   130 
   126         {
   131 	for (TUint i = 0; i < KUsbMsMaxDrives; i++)
   127         iBytesRead[i] = 0;
   132 		{
   128         iBytesWritten[i] = 0;
   133 		iBytesRead[i] = 0;
   129         }
   134 		iBytesWritten[i] = 0;
   130     }
   135 		}
       
   136 	}
       
   137 
   131 
   138 #ifdef MSDC_TESTMODE
   132 #ifdef MSDC_TESTMODE
   139 CScsiServerProtocol::CScsiServerProtocol(CDriveManager& aDriveManager, TTestParser* aTestParser)
   133 CScsiServerProtocol::CScsiServerProtocol(CDriveManager& aDriveManager, TTestParser* aTestParser)
   140 :   iDriveManager(aDriveManager),
   134 :   iDriveManager(aDriveManager),
   141     iTestParser(aTestParser)
   135     iTestParser(aTestParser)
   142 	{
   136     {
   143     __MSFNLOG
   137     iWriteTransferPublisher = CUsbWriteTransferPublisher::NewL(iBytesWritten);
   144 
   138     iReadTransferPublisher = CUsbReadTransferPublisher::NewL(iBytesRead);
   145 	iWriteTransferPublisher = CUsbWriteTransferPublisher::NewL(iBytesWritten);
   139 
   146 	iReadTransferPublisher = CUsbReadTransferPublisher::NewL(iBytesRead);
   140     for (TUint i = 0; i < KUsbMsMaxDrives; i++)
   147 
   141         {
   148 	for (TUint i = 0; i < KUsbMsMaxDrives; i++)
   142         iBytesRead[i] = 0;
   149 		{
   143         iBytesWritten[i] = 0;
   150 		iBytesRead[i] = 0;
   144         }
   151 		iBytesWritten[i] = 0;
   145     }
   152 		}
       
   153 	}
       
   154 #endif
   146 #endif
   155 
   147 
   156 
   148 
   157 CScsiServerProtocol::~CScsiServerProtocol()
   149 CScsiServerProtocol::~CScsiServerProtocol()
   158 	{
   150     {
   159     __MSFNLOG
       
   160     iDataBuf.Close();
   151     iDataBuf.Close();
   161 	delete iWriteTransferPublisher;
   152     delete iWriteTransferPublisher;
   162 	delete iReadTransferPublisher;
   153     delete iReadTransferPublisher;
   163 	}
   154     }
   164 
   155 
   165 
   156 
   166 void CScsiServerProtocol::ConstructL()
   157 void CScsiServerProtocol::ConstructL()
   167 	{
   158     {
   168     __MSFNLOG
   159     }
   169 	}
       
   170 
   160 
   171 
   161 
   172 /**
   162 /**
   173 Associates the transport with the protocol. Called during initialisation of the controller.
   163 Associates the transport with the protocol. Called during initialisation of the controller.
   174 
   164 
   175 @param aTransport pointer to the transport object
   165 @param aTransport pointer to the transport object
   176 */
   166 */
   177 void CScsiServerProtocol::RegisterTransport(MDeviceTransport* aTransport)
   167 void CScsiServerProtocol::RegisterTransport(MDeviceTransport* aTransport)
   178 	{
   168     {
   179     __MSFNLOG
   169     iTransport = aTransport;
   180 	iTransport = aTransport;
   170     }
   181 	}
       
   182 
   171 
   183 
   172 
   184 /**
   173 /**
   185 Called by the Transport when it detects that the USB device is either running
   174 Called by the Transport when it detects that the USB device is either running
   186 at High Speed or is at least capable of HS operation. The Protocol can use this
   175 at High Speed or is at least capable of HS operation. The Protocol can use this
   189 This function is preferably called before actual MS data transfer operation
   178 This function is preferably called before actual MS data transfer operation
   190 starts, and usually only once.
   179 starts, and usually only once.
   191 
   180 
   192 */
   181 */
   193 void CScsiServerProtocol::ReportHighSpeedDevice()
   182 void CScsiServerProtocol::ReportHighSpeedDevice()
   194 	{
   183     {
   195     __MSFNLOG
       
   196     iMediaWriteMan.ReportHighSpeedDevice();
   184     iMediaWriteMan.ReportHighSpeedDevice();
   197 	}
   185     }
   198 
   186 
   199 
   187 
   200 void CScsiServerProtocol::SetParameters(const TMassStorageConfig& aConfig)
   188 void CScsiServerProtocol::SetParameters(const TMassStorageConfig& aConfig)
   201 	{
   189     {
   202     __MSFNLOG
   190     iConfig = aConfig;
   203 	iConfig = aConfig;
   191     }
   204 	}
       
   205 
   192 
   206 
   193 
   207 /**
   194 /**
   208 Called by the transport layer when a packet is available for decoding.
   195 Called by the transport layer when a packet is available for decoding.
   209 If an error occurs, the sense code is updated and EFalse is returned.
   196 If an error occurs, the sense code is updated and EFalse is returned.
   211 @param aData
   198 @param aData
   212 
   199 
   213 @return  ETrue if command was decoded and executed successfully
   200 @return  ETrue if command was decoded and executed successfully
   214 */
   201 */
   215 TBool CScsiServerProtocol::DecodePacket(TPtrC8& aData, TUint8 aLun)
   202 TBool CScsiServerProtocol::DecodePacket(TPtrC8& aData, TUint8 aLun)
   216 	{
   203     {
   217     __MSFNLOG
       
   218     TScsiServerReq* cdb = NULL;
   204     TScsiServerReq* cdb = NULL;
   219     TRAPD(err, cdb = cdb->CreateL(static_cast<TScsiServerReq::TOperationCode>(aData[0]), aData));
   205     TRAPD(err, cdb = cdb->CreateL(static_cast<TScsiServerReq::TOperationCode>(aData[0]), aData));
   220 
   206 
   221     TBool decodeGood = EFalse;
   207     TBool decodeGood = EFalse;
   222     if (err == KErrNotSupported)
   208     if (err == KErrNotSupported)
   223     	iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidCmdCode);
   209         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidCmdCode);
   224 	else if (err != KErrNone)
   210     else if (err != KErrNone)
   225 		iSenseInfo.SetSense(TSenseInfo::EAbortedCommand, TSenseInfo::EInsufficientRes);
   211         iSenseInfo.SetSense(TSenseInfo::EAbortedCommand, TSenseInfo::EInsufficientRes);
   226     else if (cdb->iNaca) // Check the CONTROL byte
   212     else if (cdb->iNaca) // Check the CONTROL byte
   227 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   213         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   228     else if (cdb->iLink)
   214     else if (cdb->iLink)
   229         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   215         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   230     else
   216     else
   231         {
   217         {
   232         TScsiServerReq::TOperationCode operationCode = cdb->iOperationCode;
   218         TScsiServerReq::TOperationCode operationCode = cdb->iOperationCode;
   289                 iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidCmdCode);
   275                 iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidCmdCode);
   290                 break;
   276                 break;
   291                 }
   277                 }
   292             }
   278             }
   293         __PRINT1(_L("DecodePacket result = %d"), iSenseInfo.SenseOk());
   279         __PRINT1(_L("DecodePacket result = %d"), iSenseInfo.SenseOk());
   294     	decodeGood = iSenseInfo.SenseOk();
   280         decodeGood = iSenseInfo.SenseOk();
   295         }
   281         }
   296 
   282 
   297     delete cdb;
   283     delete cdb;
   298     return decodeGood;
   284     return decodeGood;
   299 	}
   285     }
   300 
   286 
   301 
   287 
   302 /**
   288 /**
   303 Checks if drive ready
   289 Checks if drive ready
   304 
   290 
   305 @param aLun Logic unit number
   291 @param aLun Logic unit number
   306 @return pointer to drive correspondent to LUN if drive mounted and ready, NULL otherwise
   292 @return pointer to drive correspondent to LUN if drive mounted and ready, NULL otherwise
   307 */
   293 */
   308 CMassStorageDrive* CScsiServerProtocol::GetCheckDrive()
   294 CMassStorageDrive* CScsiServerProtocol::GetCheckDrive()
   309 	{
   295     {
   310     __MSFNLOG
       
   311 #ifdef MSDC_TESTMODE
   296 #ifdef MSDC_TESTMODE
   312     if (iTestParser && iTestParser->SenseError() != TTestParser::ETestSenseErrorNoSense)
   297     if (iTestParser && iTestParser->SenseError() != TTestParser::ETestSenseErrorNoSense)
   313         {
   298         {
   314         switch (iTestParser->SenseError())
   299         switch (iTestParser->SenseError())
   315             {
   300             {
   330         iTestParser->ClrSenseError();
   315         iTestParser->ClrSenseError();
   331         return NULL;
   316         return NULL;
   332         }
   317         }
   333 #endif
   318 #endif
   334 
   319 
   335 	CMassStorageDrive* drive = iDriveManager.Drive(iLun);
   320     CMassStorageDrive* drive = iDriveManager.Drive(iLun);
   336 	CMassStorageDrive::TMountState mountState = drive->MountState();
   321     CMassStorageDrive::TMountState mountState = drive->MountState();
   337 
   322 
   338 	if (mountState == CMassStorageDrive::EDisconnected || mountState == CMassStorageDrive::EConnecting)
   323     if (mountState == CMassStorageDrive::EDisconnected || mountState == CMassStorageDrive::EConnecting)
   339 		{
   324         {
   340 		__PRINT(_L("Drive disconnected\n"));
   325         __PRINT(_L("Drive disconnected\n"));
   341 		iSenseInfo.SetSense(TSenseInfo::ENotReady,
   326         iSenseInfo.SetSense(TSenseInfo::ENotReady,
   342 							TSenseInfo::EMediaNotPresent);
   327                             TSenseInfo::EMediaNotPresent);
   343 		return NULL;
   328         return NULL;
   344 		}
   329         }
   345 
   330 
   346 	TLocalDriveRef::TDriveState state = drive->CheckDriveState();
   331     TLocalDriveRef::TDriveState state = drive->CheckDriveState();
   347 	if (state == TLocalDriveRef::EMediaNotPresent || state == TLocalDriveRef::ELocked)
   332     if (state == TLocalDriveRef::EMediaNotPresent || state == TLocalDriveRef::ELocked)
   348 		{
   333         {
   349 		__PRINT1(_L("Media not present or locked. (state =0x%X)\n"),state);
   334         __PRINT1(_L("Media not present or locked. (state =0x%X)\n"),state);
   350 		iSenseInfo.SetSense(TSenseInfo::ENotReady, TSenseInfo::EMediaNotPresent);
   335         iSenseInfo.SetSense(TSenseInfo::ENotReady, TSenseInfo::EMediaNotPresent);
   351 		return NULL;
   336         return NULL;
   352 		}
   337         }
   353 
   338 
   354 	if (drive->IsMediaChanged(ETrue))  //reset "media changed" status
   339     if (drive->IsMediaChanged(ETrue))  //reset "media changed" status
   355 		{
   340         {
   356 		__PRINT(_L("Media was changed\n"));
   341         __PRINT(_L("Media was changed\n"));
   357 		// SAM-2 Section 5.9.5 Unit Attention Condition
   342         // SAM-2 Section 5.9.5 Unit Attention Condition
   358 		iSenseInfo.SetSense(TSenseInfo::EUnitAttention, TSenseInfo::ENotReadyToReadyChange);
   343         iSenseInfo.SetSense(TSenseInfo::EUnitAttention, TSenseInfo::ENotReadyToReadyChange);
   359 		iDriveManager.Connect(iLun);   //publish event to USB app
   344         iDriveManager.Connect(iLun);   //publish event to USB app
   360 		return NULL;
   345         return NULL;
   361 		}
   346         }
   362 
   347 
   363 	if (mountState == CMassStorageDrive::EDisconnecting)
   348     if (mountState == CMassStorageDrive::EDisconnecting)
   364 		{
   349         {
   365 		__PRINT(_L("Drive disconnecting\n"));
   350         __PRINT(_L("Drive disconnecting\n"));
   366 		iSenseInfo.SetSense(TSenseInfo::ENotReady,
   351         iSenseInfo.SetSense(TSenseInfo::ENotReady,
   367 							TSenseInfo::EMediaNotPresent);
   352                             TSenseInfo::EMediaNotPresent);
   368 		return NULL;
   353         return NULL;
   369 		}
   354         }
   370 
   355 
   371 	return drive;
   356     return drive;
   372 	}
   357     }
   373 
   358 
   374 
   359 
   375 /**
   360 /**
   376 Command Parser for the UNIT READY command (0x00)
   361 Command Parser for the UNIT READY command (0x00)
   377 
   362 
   378 @param aLun Logic unit number
   363 @param aLun Logic unit number
   379 @return ETrue if successful,
   364 @return ETrue if successful,
   380 */
   365 */
   381 TBool CScsiServerProtocol::HandleUnitReady()
   366 TBool CScsiServerProtocol::HandleUnitReady()
   382 	{
   367     {
   383     __MSFNLOG
   368     return GetCheckDrive() ? ETrue : EFalse;
   384 	return GetCheckDrive() ? ETrue : EFalse;
   369     }
   385 	}
       
   386 
   370 
   387 
   371 
   388 /**
   372 /**
   389 Command Parser for the REQUEST SENSE command (0x03)
   373 Command Parser for the REQUEST SENSE command (0x03)
   390 
   374 
   391 @return ETrue if successful,
   375 @return ETrue if successful,
   392 */
   376 */
   393 TBool CScsiServerProtocol::HandleRequestSense(const TScsiServerReq& aRequest)
   377 TBool CScsiServerProtocol::HandleRequestSense(const TScsiServerReq& aRequest)
   394 	{
   378     {
   395     __MSFNLOG
       
   396     const TScsiServerRequestSenseReq request = static_cast<const TScsiServerRequestSenseReq&>(aRequest);
   379     const TScsiServerRequestSenseReq request = static_cast<const TScsiServerRequestSenseReq&>(aRequest);
   397 	__PRINT1(_L("length = %d\n"), request.iAllocationLength);
   380     __PRINT1(_L("length = %d\n"), request.iAllocationLength);
   398 
   381 
   399     TScsiServerRequestSenseResp requestSense;
   382     TScsiServerRequestSenseResp requestSense;
   400     requestSense.iAllocationLength = request.iAllocationLength;
   383     requestSense.iAllocationLength = request.iAllocationLength;
   401 
   384 
   402     requestSense.SetResponseCode(TScsiServerRequestSenseResp::ECurrentErrors);
   385     requestSense.SetResponseCode(TScsiServerRequestSenseResp::ECurrentErrors);
   403     requestSense.iSensePtr = &iSenseInfo;
   386     requestSense.iSensePtr = &iSenseInfo;
   404     requestSense.Encode(iCommandBuf);
   387     requestSense.Encode(iCommandBuf);
   405 
   388 
   406 	__PRINT4(_L("Response=0x%x Sense=0x%x, Additional=0x%x, Qualifier=0x%x\n"),
   389     __PRINT4(_L("Response=0x%x Sense=0x%x, Additional=0x%x, Qualifier=0x%x\n"),
   407 				iCommandBuf[0], iCommandBuf[02], iCommandBuf[12], iCommandBuf[13]);
   390                 iCommandBuf[0], iCommandBuf[02], iCommandBuf[12], iCommandBuf[13]);
   408 
   391 
   409 	TPtrC8 writeBuf = iCommandBuf.Left(request.iAllocationLength);
   392     TPtrC8 writeBuf = iCommandBuf.Left(request.iAllocationLength);
   410 	iTransport->SetupDataIn(writeBuf);
   393     iTransport->SetupDataIn(writeBuf);
   411 
   394 
   412 	// clear the sense info
   395     // clear the sense info
   413 	iSenseInfo.SetSense(TSenseInfo::ENoSense);
   396     iSenseInfo.SetSense(TSenseInfo::ENoSense);
   414 	return ETrue;
   397     return ETrue;
   415 	}
   398     }
   416 
   399 
   417 
   400 
   418 /**
   401 /**
   419 Command Parser for the INQUIRY command (0x12)
   402 Command Parser for the INQUIRY command (0x12)
   420 
   403 
   421 @param aLun Logic unit number
   404 @param aLun Logic unit number
   422 @return ETrue if successful,
   405 @return ETrue if successful,
   423 */
   406 */
   424 TBool CScsiServerProtocol::HandleInquiry(const TScsiServerReq& aRequest)
   407 TBool CScsiServerProtocol::HandleInquiry(const TScsiServerReq& aRequest)
   425 	{
   408     {
   426     __MSFNLOG
       
   427     const TScsiServerInquiryReq request = static_cast<const TScsiServerInquiryReq&>(aRequest);
   409     const TScsiServerInquiryReq request = static_cast<const TScsiServerInquiryReq&>(aRequest);
   428 
   410 
   429 	if (request.iCmdDt || request.iEvpd || request.iPage || iLun >= KUsbMsMaxDrives)
   411     if (request.iCmdDt || request.iEvpd || request.iPage || iLun >= KUsbMsMaxDrives)
   430 		{
   412         {
   431 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   413         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   432 		return EFalse;
   414         return EFalse;
   433 		}
   415         }
   434 
   416 
   435     TScsiServerInquiryResp inquiry(iConfig);
   417     TScsiServerInquiryResp inquiry(iConfig);
   436 
   418 
   437     inquiry.SetAllocationLength(request.iAllocationLength);
   419     inquiry.SetAllocationLength(request.iAllocationLength);
   438 
   420 
   446 
   428 
   447     inquiry.Encode(iCommandBuf);
   429     inquiry.Encode(iCommandBuf);
   448 
   430 
   449     TUint length = inquiry.Length();
   431     TUint length = inquiry.Length();
   450 
   432 
   451 	TPtrC8 writeBuf = iCommandBuf.Left(length);
   433     TPtrC8 writeBuf = iCommandBuf.Left(length);
   452 	iTransport->SetupDataIn(writeBuf);
   434     iTransport->SetupDataIn(writeBuf);
   453 
   435 
   454 	iSenseInfo.SetSense(TSenseInfo::ENoSense);
   436     iSenseInfo.SetSense(TSenseInfo::ENoSense);
   455 	return ETrue;
   437     return ETrue;
   456 	}
   438     }
   457 
   439 
   458 
   440 
   459 /**
   441 /**
   460  Command Parser for the START STOP UNIT command (0x1B)
   442  Command Parser for the START STOP UNIT command (0x1B)
   461 
   443 
   462  @param aData command data (started form position 1)
   444  @param aData command data (started form position 1)
   463  @param aLun Logic unit number
   445  @param aLun Logic unit number
   464  @return ETrue if successful, TFalse otherwise
   446  @return ETrue if successful, TFalse otherwise
   465  */
   447  */
   466 TBool CScsiServerProtocol::HandleStartStopUnit(const TScsiServerReq& aRequest)
   448 TBool CScsiServerProtocol::HandleStartStopUnit(const TScsiServerReq& aRequest)
   467 	{
   449     {
   468     __MSFNLOG
   450     const TScsiServerStartStopUnitReq request = static_cast<const TScsiServerStartStopUnitReq&>(aRequest);
   469 
   451 
   470 	const TScsiServerStartStopUnitReq request = static_cast<const TScsiServerStartStopUnitReq&>(aRequest);
   452     if (request.iLoej)
   471 
   453         {
   472 	if (request.iLoej)
   454         if(request.iStart)  //Start unit
   473 		{
   455             {
   474 		if(request.iStart)	//Start unit
   456             iDriveManager.Connect(iLun);
   475 			{
   457             __PRINT(_L("Load media\n"));
   476 			iDriveManager.Connect(iLun);
       
   477 			__PRINT(_L("Load media\n"));
       
   478 
   458 
   479             // rd/wr publisher
   459             // rd/wr publisher
   480 			iBytesRead[iLun] = 0;
   460             iBytesRead[iLun] = 0;
   481 			iBytesWritten[iLun] = 0;
   461             iBytesWritten[iLun] = 0;
   482 
   462 
   483 			// publish the initial values
   463             // publish the initial values
   484 			iWriteTransferPublisher->DoPublishDataTransferredEvent();
   464             iWriteTransferPublisher->DoPublishDataTransferredEvent();
   485 			iReadTransferPublisher->DoPublishDataTransferredEvent();
   465             iReadTransferPublisher->DoPublishDataTransferredEvent();
   486 			}
   466             }
   487 		else		//Stop unit
   467         else        //Stop unit
   488 			{
   468             {
   489 			iDriveManager.SetCritical(iLun, EFalse);
   469             iDriveManager.SetCritical(iLun, EFalse);
   490 			iDriveManager.Disconnect(iLun);
   470             iDriveManager.Disconnect(iLun);
   491 			__PRINT(_L("Unload media\n"));
   471             __PRINT(_L("Unload media\n"));
   492 			}
   472             }
   493 		}
   473         }
   494 
   474 
   495 	if (request.iImmed)
   475     if (request.iImmed)
   496 		{
   476         {
   497 		return ETrue;
   477         return ETrue;
   498 		}
   478         }
   499 
   479 
   500 	CMassStorageDrive* drive = iDriveManager.Drive(iLun);
   480     CMassStorageDrive* drive = iDriveManager.Drive(iLun);
   501 
   481 
   502 	TInt  timeLeft (20);   // 1 sec timeout
   482     TInt  timeLeft (20);   // 1 sec timeout
   503 	CMassStorageDrive::TMountState mountState;
   483     CMassStorageDrive::TMountState mountState;
   504 
   484 
   505 	do
   485     do
   506 		{
   486         {
   507 		User::After(1000 * 50);		// 50 mSec
   487         User::After(1000 * 50);     // 50 mSec
   508 		--timeLeft;
   488         --timeLeft;
   509 		mountState = drive->MountState();
   489         mountState = drive->MountState();
   510 
   490 
   511 		if ((!request.iStart && mountState != CMassStorageDrive::EConnected)
   491         if ((!request.iStart && mountState != CMassStorageDrive::EConnected)
   512 			 ||
   492              ||
   513 			 (request.iStart &&
   493              (request.iStart &&
   514 				(mountState == CMassStorageDrive::EDisconnecting ||
   494                 (mountState == CMassStorageDrive::EDisconnecting ||
   515                mountState == CMassStorageDrive::EConnected)))
   495                mountState == CMassStorageDrive::EConnected)))
   516 			{
   496             {
   517 			return ETrue;
   497             return ETrue;
   518 			}
   498             }
   519 		} while (timeLeft>0);
   499         } while (timeLeft>0);
   520 
   500 
   521 	//timeout happend
   501     //timeout happend
   522 	iSenseInfo.SetSense(TSenseInfo::ENotReady,
   502     iSenseInfo.SetSense(TSenseInfo::ENotReady,
   523 						TSenseInfo::EAscLogicalUnitDoesNotRespondToSelection);
   503                         TSenseInfo::EAscLogicalUnitDoesNotRespondToSelection);
   524 	return EFalse;
   504     return EFalse;
   525 	}
   505     }
   526 
   506 
   527 
   507 
   528 /**
   508 /**
   529 Command Parser for the PREVENT/ALLOW MEDIA REMOVAL command (0x1E)
   509 Command Parser for the PREVENT/ALLOW MEDIA REMOVAL command (0x1E)
   530 
   510 
   531 @param aData command data (started form position 1)
   511 @param aData command data (started form position 1)
   532 @param aLun Logic unit number
   512 @param aLun Logic unit number
   533 @return ETrue if successful.
   513 @return ETrue if successful.
   534 */
   514 */
   535 TBool CScsiServerProtocol::HandlePreventMediaRemoval(const TScsiServerReq& aRequest)
   515 TBool CScsiServerProtocol::HandlePreventMediaRemoval(const TScsiServerReq& aRequest)
   536 	{
   516     {
   537     __MSFNLOG
   517     const TScsiServerPreventMediaRemovalReq& request = static_cast<const TScsiServerPreventMediaRemovalReq&>(aRequest);
   538 	const TScsiServerPreventMediaRemovalReq& request = static_cast<const TScsiServerPreventMediaRemovalReq&>(aRequest);
   518     CMassStorageDrive* drive = GetCheckDrive();
   539 	__FNLOG("CScsiProtocol::HandlePreventMediaRemoval");
   519 
   540 	CMassStorageDrive* drive = GetCheckDrive();
   520     if (drive == NULL)
   541 
   521         {
   542 	if (drive == NULL)
   522         return EFalse;
   543 		{
   523         }
   544 		return EFalse;
   524     iDriveManager.SetCritical(iLun, request.iPrevent);
   545 		}
   525     return ETrue;
   546 	iDriveManager.SetCritical(iLun, request.iPrevent);
   526     }
   547 	return ETrue;
       
   548 	}
       
   549 
   527 
   550 
   528 
   551 /** Cancel active state, Invoked by transnport when it stops */
   529 /** Cancel active state, Invoked by transnport when it stops */
   552 TInt CScsiServerProtocol::Cancel()
   530 TInt CScsiServerProtocol::Cancel()
   553 	{
   531     {
   554     __MSFNLOG
   532     iDriveManager.SetCritical(CDriveManager::KAllLuns, EFalse);
   555 	iDriveManager.SetCritical(CDriveManager::KAllLuns, EFalse);
   533     return KErrNone;
   556 	return KErrNone;
   534     }
   557 	}
       
   558 
   535 
   559 
   536 
   560 TBool CScsiServerProtocol::HandleReadFormatCapacities(const TScsiServerReq& aRequest)
   537 TBool CScsiServerProtocol::HandleReadFormatCapacities(const TScsiServerReq& aRequest)
   561 /**
   538 /**
   562  * Command Parser for the READ FORMAT CAPACITIES command (0x23)
   539  * Command Parser for the READ FORMAT CAPACITIES command (0x23)
   563  *
   540  *
   564  * @return ETrue if successful, else a standard Symbian OS error code.
   541  * @return ETrue if successful, else a standard Symbian OS error code.
   565  */
   542  */
   566 	{
   543     {
   567     __MSFNLOG
   544     const TScsiServerReadFormatCapacitiesReq& request = static_cast<const TScsiServerReadFormatCapacitiesReq&>(aRequest);
   568 	const TScsiServerReadFormatCapacitiesReq& request = static_cast<const TScsiServerReadFormatCapacitiesReq&>(aRequest);
       
   569 
   545 
   570     CMassStorageDrive* drive = NULL;
   546     CMassStorageDrive* drive = NULL;
   571     for (TInt i = 0; i < 10; i++)
   547     for (TInt i = 0; i < 10; i++)
   572         {
   548         {
   573         drive = GetCheckDrive();
   549         drive = GetCheckDrive();
   576             break;
   552             break;
   577             }
   553             }
   578         User::After(100000);
   554         User::After(100000);
   579         }
   555         }
   580 
   556 
   581 	if (!drive)
   557     if (!drive)
   582 		{
   558         {
   583         return EFalse;
   559         return EFalse;
   584 		}
   560         }
   585 
   561 
   586 	TUint32 numBlocks = I64LOW(drive->MediaParams().NumBlocks());
   562     TUint32 numBlocks = I64LOW(drive->MediaParams().NumBlocks());
   587 
   563 
   588     TScsiServerReadFormatCapacitiesResp response(request.AllocationLength());
   564     TScsiServerReadFormatCapacitiesResp response(request.AllocationLength());
   589     response.SetNumberBlocks(numBlocks);
   565     response.SetNumberBlocks(numBlocks);
   590 
   566 
   591     response.Encode(iCommandBuf);
   567     response.Encode(iCommandBuf);
   592 	TPtrC8 writeBuf = iCommandBuf;
   568     TPtrC8 writeBuf = iCommandBuf;
   593 	iTransport->SetupDataIn(writeBuf);
   569     iTransport->SetupDataIn(writeBuf);
   594 	return ETrue;
   570     return ETrue;
   595 	}
   571     }
   596 
   572 
   597 
   573 
   598 /**
   574 /**
   599 Command Parser for the READ CAPACITY(10) command (0x25)
   575 Command Parser for the READ CAPACITY(10) command (0x25)
   600 
   576 
   601 @param aData command data (started form position 1)
   577 @param aData command data (started form position 1)
   602 @param aLun Logic unit number
   578 @param aLun Logic unit number
   603 @return ETrue if successful.
   579 @return ETrue if successful.
   604 */
   580 */
   605 TBool CScsiServerProtocol::HandleReadCapacity10(const TScsiServerReq& aRequest)
   581 TBool CScsiServerProtocol::HandleReadCapacity10(const TScsiServerReq& aRequest)
   606 	{
   582     {
   607     __MSFNLOG
   583     const TScsiServerReadCapacity10Req& request = static_cast<const TScsiServerReadCapacity10Req&>(aRequest);
   608 	const TScsiServerReadCapacity10Req& request = static_cast<const TScsiServerReadCapacity10Req&>(aRequest);
   584     CMassStorageDrive* drive = GetCheckDrive();
   609 	CMassStorageDrive* drive = GetCheckDrive();
   585     if (drive == NULL)
   610 	if (drive == NULL)
   586         {
   611 		{
   587         return EFalse;
   612 		return EFalse;
   588         }
   613 		}
   589 
   614 
   590     if (request.iPmi || request.iLogicalBlockAddress)   //do not support partial medium indicator
   615 	if (request.iPmi || request.iLogicalBlockAddress)   //do not support partial medium indicator
   591         {
   616 		{
   592         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   617 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   593         return EFalse;
   618 		return EFalse;
   594         }
   619 		}
       
   620 
   595 
   621     TScsiServerReadCapacity10Resp response;
   596     TScsiServerReadCapacity10Resp response;
   622     response.Set(drive->MediaParams().BlockSize(), drive->MediaParams().NumBlocks());
   597     response.Set(drive->MediaParams().BlockSize(), drive->MediaParams().NumBlocks());
   623     response.Encode(iCommandBuf);
   598     response.Encode(iCommandBuf);
   624 
   599 
   625 	TPtrC8 writeBuf = iCommandBuf;
   600     TPtrC8 writeBuf = iCommandBuf;
   626 	iTransport->SetupDataIn(writeBuf);
   601     iTransport->SetupDataIn(writeBuf);
   627 
   602 
   628 	return KErrNone;
   603     return KErrNone;
   629 	}
   604     }
   630 
   605 
   631 
   606 
   632 /**
   607 /**
   633 Command Parser for the READ10 command (0x28)
   608 Command Parser for the READ10 command (0x28)
   634 
   609 
   635 @param aData command data (started form position 1)
   610 @param aData command data (started form position 1)
   636 @param aLun Logic unit number
   611 @param aLun Logic unit number
   637 @return ETrue if successful.
   612 @return ETrue if successful.
   638 */
   613 */
   639 TBool CScsiServerProtocol::HandleRead10(const TScsiServerReq& aRequest)
   614 TBool CScsiServerProtocol::HandleRead10(const TScsiServerReq& aRequest)
   640 	{
   615     {
   641     __MSFNLOG
   616     const TScsiServerRead10Req& request = static_cast<const TScsiServerRead10Req&>(aRequest);
   642 	const TScsiServerRead10Req& request = static_cast<const TScsiServerRead10Req&>(aRequest);
   617     CMassStorageDrive* drive = GetCheckDrive();
   643 	CMassStorageDrive* drive = GetCheckDrive();
   618     if (drive == NULL)
   644 	if (drive == NULL)
   619         {
   645 		{
   620         return EFalse;
   646 		return EFalse;
   621         }
   647 		}
   622 
   648 
   623     if (request.iProtect)
   649 	if (request.iProtect)
   624         {
   650 		{
   625         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   651 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   626         return EFalse;
   652 		return EFalse;
   627         }
   653 		}
   628 
   654 
   629     if (!request.iTransferLength)
   655 	if (!request.iTransferLength)
   630         {
   656 		{
   631         return ETrue; // do nothing - this is not an error
   657 		return ETrue; // do nothing - this is not an error
   632         }
   658 		}
       
   659 
   633 
   660     TUint32 blockSize = drive->MediaParams().BlockSize();
   634     TUint32 blockSize = drive->MediaParams().BlockSize();
   661 
   635 
   662 	const TInt64 bOffset = static_cast<TInt64>(request.iLogicalBlockAddress) * blockSize;
   636     const TInt64 bOffset = static_cast<TInt64>(request.iLogicalBlockAddress) * blockSize;
   663 	const TInt bLength = request.iTransferLength * blockSize;
   637     const TInt bLength = request.iTransferLength * blockSize;
   664 	const TInt64 theEnd = bOffset + bLength;
   638     const TInt64 theEnd = bOffset + bLength;
   665 
   639 
   666 	if (theEnd > drive->MediaParams().Size())  //check if media big enough for this request
   640     if (theEnd > drive->MediaParams().Size())  //check if media big enough for this request
   667 		{
   641         {
   668 		__PRINT(_L("err - Request ends out of media\n"));
   642         __PRINT(_L("err - Request ends out of media\n"));
   669 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::ELbaOutOfRange);
   643         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::ELbaOutOfRange);
   670 		return EFalse;
   644         return EFalse;
   671 		}
   645         }
   672 
   646 
   673 	// check if our buffer can hold requested data
   647     // check if our buffer can hold requested data
   674 	if (iDataBuf.MaxLength() < bLength)
   648     if (iDataBuf.MaxLength() < bLength)
   675 		{
   649         {
   676         TRAPD(err,iDataBuf.ReAllocL(bLength));
   650         TRAPD(err,iDataBuf.ReAllocL(bLength));
   677         if (err)
   651         if (err)
   678             {
   652             {
   679             __PRINT(_L("err - Buffer too small\n"));
   653             __PRINT(_L("err - Buffer too small\n"));
   680             iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   654             iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   681             return EFalse;
   655             return EFalse;
   682             }
   656             }
   683 		}
   657         }
   684 
   658 
   685     iDataBuf.SetLength(bLength);
   659     iDataBuf.SetLength(bLength);
   686 	TInt err = drive->Read(bOffset, bLength, iDataBuf);
   660     TInt err = drive->Read(bOffset, bLength, iDataBuf);
   687 	if (err != KErrNone)
   661     if (err != KErrNone)
   688 		{
   662         {
   689 		__PRINT1(_L("Read failed, err=%d\n"), err);
   663         __PRINT1(_L("Read failed, err=%d\n"), err);
   690 		iSenseInfo.SetSense(TSenseInfo::ENotReady, TSenseInfo::EMediaNotPresent);
   664         iSenseInfo.SetSense(TSenseInfo::ENotReady, TSenseInfo::EMediaNotPresent);
   691 		return EFalse;
   665         return EFalse;
   692 		}
   666         }
   693 
   667 
   694 	TPtrC8 writeBuf = iDataBuf;
   668     TPtrC8 writeBuf = iDataBuf;
   695 
   669 
   696     // rd publisher
   670     // rd publisher
   697 	iBytesRead[iLun] += writeBuf.Length();
   671     iBytesRead[iLun] += writeBuf.Length();
   698 	iReadTransferPublisher->StartTimer();
   672     iReadTransferPublisher->StartTimer();
   699 
   673 
   700 	// Set up data write to the host
   674     // Set up data write to the host
   701 #ifdef MSDC_TESTMODE
   675 #ifdef MSDC_TESTMODE
   702     if (iTestParser)
   676     if (iTestParser)
   703         {
   677         {
   704         TBool test = iTestParser->DInSearch(writeBuf);
   678         TBool test = iTestParser->DInSearch(writeBuf);
   705         }
   679         }
   706 #endif
   680 #endif
   707 	iTransport->SetupDataIn(writeBuf);
   681     iTransport->SetupDataIn(writeBuf);
   708 	return ETrue;
   682     return ETrue;
   709 	}
   683     }
   710 
   684 
   711 
   685 
   712 /**
   686 /**
   713 Command Parser for the WRITE(10) command (0x2A)
   687 Command Parser for the WRITE(10) command (0x2A)
   714 
   688 
   715 @param aData command data (started form position 1)
   689 @param aData command data (started form position 1)
   716 @param aLun Logic unit number
   690 @param aLun Logic unit number
   717 @return ETrue if successful.
   691 @return ETrue if successful.
   718 */
   692 */
   719 TBool CScsiServerProtocol::HandleWrite10(const TScsiServerReq& aRequest)
   693 TBool CScsiServerProtocol::HandleWrite10(const TScsiServerReq& aRequest)
   720 	{
   694     {
   721     __MSFNLOG
   695     const TScsiServerWrite10Req& request = static_cast<const TScsiServerWrite10Req&>(aRequest);
   722 	const TScsiServerWrite10Req& request = static_cast<const TScsiServerWrite10Req&>(aRequest);
   696     CMassStorageDrive* drive = GetCheckDrive();
   723 	CMassStorageDrive* drive = GetCheckDrive();
   697     if (drive == NULL)
   724 	if (drive == NULL)
   698         {
   725 		{
   699         return EFalse;
   726 		return EFalse;
   700         }
   727 		}
   701     if (request.iProtect)
   728 	if (request.iProtect)
   702         {
   729 		{
   703         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   730 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   704         return EFalse;
   731 		return EFalse;
   705         }
   732 		}
   706 
   733 
   707     if (!request.iTransferLength)
   734 	if (!request.iTransferLength)
   708         {
   735 		{
   709         return ETrue; // do nothing - this is not an error
   736 		return ETrue; // do nothing - this is not an error
   710         }
   737 		}
       
   738 
   711 
   739     const TMediaParams& params = drive->MediaParams();
   712     const TMediaParams& params = drive->MediaParams();
   740 
   713 
   741 	if (params.IsWriteProtected() ||
   714     if (params.IsWriteProtected() ||
   742 		params.IsLocked())
   715         params.IsLocked())
   743 		{
   716         {
   744 		iSenseInfo.SetSense(TSenseInfo::EDataProtection, TSenseInfo::EWriteProtected);
   717         iSenseInfo.SetSense(TSenseInfo::EDataProtection, TSenseInfo::EWriteProtected);
   745 		return EFalse;
   718         return EFalse;
   746 		}
   719         }
   747 
   720 
   748     TInt64 theEnd = iMediaWriteMan.Start(request.iLogicalBlockAddress, request.iTransferLength, params.BlockSize());
   721     TInt64 theEnd = iMediaWriteMan.Start(request.iLogicalBlockAddress, request.iTransferLength, params.BlockSize());
   749 	if (theEnd > params.Size())  //check if media big enough for this request
   722     if (theEnd > params.Size())  //check if media big enough for this request
   750 		{
   723         {
   751 		__PRINT(_L("err - Request ends out of media\n"));
   724         __PRINT(_L("err - Request ends out of media\n"));
   752 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::ELbaOutOfRange);
   725         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::ELbaOutOfRange);
   753 		return EFalse;
   726         return EFalse;
   754 		}
   727         }
   755 
   728 
   756     TUint32 thisLength = iMediaWriteMan.GetPacketLength();
   729     TUint32 thisLength = iMediaWriteMan.GetPacketLength();
   757 
   730 
   758     // check if our buffer can hold requested data
   731     // check if our buffer can hold requested data
   759     if (iDataBuf.MaxLength() < thisLength)
   732     if (iDataBuf.MaxLength() < thisLength)
   765             iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   738             iSenseInfo.SetSense(TSenseInfo::EIllegalRequest, TSenseInfo::EInvalidFieldInCdb);
   766             return EFalse;
   739             return EFalse;
   767             }
   740             }
   768         }
   741         }
   769 
   742 
   770 	iDataBuf.SetLength(thisLength);
   743     iDataBuf.SetLength(thisLength);
   771 	TPtr8 readBuf = iDataBuf.LeftTPtr(iDataBuf.Length());
   744     TPtr8 readBuf = iDataBuf.LeftTPtr(iDataBuf.Length());
   772 
   745 
   773     // wr publisher
   746     // wr publisher
   774 	iBytesWritten[iLun] += readBuf.Length();
   747     iBytesWritten[iLun] += readBuf.Length();
   775 	iWriteTransferPublisher->StartTimer();
   748     iWriteTransferPublisher->StartTimer();
   776 	iTransport->SetupDataOut(readBuf);
   749     iTransport->SetupDataOut(readBuf);
   777 	return ETrue;
   750     return ETrue;
   778 	}
   751     }
   779 
   752 
   780 
   753 
   781 void CScsiServerProtocol::MediaWriteAbort()
   754 void CScsiServerProtocol::MediaWriteAbort()
   782     {
   755     {
   783     __MSFNLOG
       
   784     iMediaWriteMan.Reset();
   756     iMediaWriteMan.Reset();
   785     iSenseInfo.SetSense(TSenseInfo::EAbortedCommand);
   757     iSenseInfo.SetSense(TSenseInfo::EAbortedCommand);
   786     }
   758     }
   787 
   759 
   788 /**
   760 /**
   795         the transfer immediately, KErrNotReady if insufficient data is
   767         the transfer immediately, KErrNotReady if insufficient data is
   796         available in the buffer so the transport should wait for it to arrive,
   768         available in the buffer so the transport should wait for it to arrive,
   797         KErrNone if command processing is complete and was successful.
   769         KErrNone if command processing is complete and was successful.
   798 */
   770 */
   799 TInt CScsiServerProtocol::MediaWritePacket(TUint& aBytesWritten)
   771 TInt CScsiServerProtocol::MediaWritePacket(TUint& aBytesWritten)
   800 	{
   772     {
   801     __MSFNLOG
       
   802     aBytesWritten = 0;
   773     aBytesWritten = 0;
   803     if (iMediaWriteMan.Active() == EFalse)
   774     if (iMediaWriteMan.Active() == EFalse)
   804         {
   775         {
   805         iSenseInfo.SetSense(TSenseInfo::EAbortedCommand);
   776         iSenseInfo.SetSense(TSenseInfo::EAbortedCommand);
   806         return KErrAbort;
   777         return KErrAbort;
   865 
   836 
   866             }
   837             }
   867         }
   838         }
   868 #endif
   839 #endif
   869 
   840 
   870 	const TInt64 bOffset = iMediaWriteMan.Offset();
   841     const TInt64 bOffset = iMediaWriteMan.Offset();
   871     iMediaWriteMan.Reset();
   842     iMediaWriteMan.Reset();
   872 
   843 
   873    	__PRINT1(_L("SCSI: writing %d bytes\n"), iDataBuf.Length());
   844     __PRINT1(_L("SCSI: writing %d bytes\n"), iDataBuf.Length());
   874 
   845 
   875     TInt err = KErrNone;
   846     TInt err = KErrNone;
   876 #ifdef MSDC_TESTMODE
   847 #ifdef MSDC_TESTMODE
   877     if (iTestParser)
   848     if (iTestParser)
   878         {
   849         {
   887             err = drive->Write(bOffset, iDataBuf);
   858             err = drive->Write(bOffset, iDataBuf);
   888             }
   859             }
   889         }
   860         }
   890 #else
   861 #else
   891     // ********* Write data to the drive ********
   862     // ********* Write data to the drive ********
   892    	err = drive->Write(bOffset, iDataBuf);
   863     err = drive->Write(bOffset, iDataBuf);
   893 #endif
   864 #endif
   894    	if (err != KErrNone)
   865     if (err != KErrNone)
   895    		{
   866         {
   896    		__PRINT1(_L("Error after write = 0x%X \n"), err);
   867         __PRINT1(_L("Error after write = 0x%X \n"), err);
   897    		iSenseInfo.SetSense(TSenseInfo::EAbortedCommand);
   868         iSenseInfo.SetSense(TSenseInfo::EAbortedCommand);
   898    		return KErrAbort;
   869         return KErrAbort;
   899    		}
   870         }
   900 
   871 
   901    	TUint thisLength = iDataBuf.Length();
   872     TUint thisLength = iDataBuf.Length();
   902     aBytesWritten = thisLength;
   873     aBytesWritten = thisLength;
   903 
   874 
   904     iMediaWriteMan.SetOffset(bOffset, thisLength);
   875     iMediaWriteMan.SetOffset(bOffset, thisLength);
   905 
   876 
   906    	if (iMediaWriteMan.BytesRemain() == 0)
   877     if (iMediaWriteMan.BytesRemain() == 0)
   907         {
   878         {
   908         return iSenseInfo.SenseOk() ? KErrNone : KErrAbort;
   879         return iSenseInfo.SenseOk() ? KErrNone : KErrAbort;
   909         }
   880         }
   910 
   881 
   911     // More data is expected - set up another request to read from the host
   882     // More data is expected - set up another request to read from the host
   912     const TUint32 nextPacketLength = iMediaWriteMan.NextPacket();
   883     const TUint32 nextPacketLength = iMediaWriteMan.NextPacket();
   913  	TUint bytesAvail = iTransport->BytesAvailable() & ~(drive->MediaParams().BlockSize()-1);
   884     TUint bytesAvail = iTransport->BytesAvailable() & ~(drive->MediaParams().BlockSize()-1);
   914 
   885 
   915  	TBool wait = EFalse;
   886     TBool wait = EFalse;
   916 
   887 
   917     thisLength = nextPacketLength;
   888     thisLength = nextPacketLength;
   918     if (bytesAvail)
   889     if (bytesAvail)
   919         {
   890         {
   920         if (bytesAvail < nextPacketLength)
   891         if (bytesAvail < nextPacketLength)
   925             thisLength = nextPacketLength;
   896             thisLength = nextPacketLength;
   926             wait = ETrue;
   897             wait = ETrue;
   927             }
   898             }
   928         }
   899         }
   929 
   900 
   930  	thisLength = (thisLength > KMaxBufSize) ? KMaxBufSize : thisLength;
   901     thisLength = (thisLength > KMaxBufSize) ? KMaxBufSize : thisLength;
   931 
   902 
   932    	iDataBuf.SetLength(thisLength);
   903     iDataBuf.SetLength(thisLength);
   933    	TPtr8 readBuf = iDataBuf.LeftTPtr(iDataBuf.Length());
   904     TPtr8 readBuf = iDataBuf.LeftTPtr(iDataBuf.Length());
   934     iTransport->SetupDataOut(readBuf);
   905     iTransport->SetupDataOut(readBuf);
   935     return wait ? KErrNotReady : KErrCompletion;
   906     return wait ? KErrNotReady : KErrCompletion;
   936 	}
   907     }
   937 
   908 
   938 
   909 
   939 /**
   910 /**
   940 Command Parser for the MODE SENSE(06) command (0x1A)
   911 Command Parser for the MODE SENSE(06) command (0x1A)
   941 
   912 
   942 @return ETrue if successful.
   913 @return ETrue if successful.
   943 */
   914 */
   944 TBool CScsiServerProtocol::HandleModeSense6(const TScsiServerReq& aRequest)
   915 TBool CScsiServerProtocol::HandleModeSense6(const TScsiServerReq& aRequest)
   945 	{
   916     {
   946     __MSFNLOG
   917     const TScsiServerModeSense6Req& request = static_cast<const TScsiServerModeSense6Req&>(aRequest);
   947 	const TScsiServerModeSense6Req& request = static_cast<const TScsiServerModeSense6Req&>(aRequest);
   918 
   948 
   919     TScsiServerModeSense6Resp response;
   949 	TScsiServerModeSense6Resp response;
       
   950     response.SetAllocationLength(request.iAllocationLength);
   920     response.SetAllocationLength(request.iAllocationLength);
   951 
   921 
   952 	if (request.iPageCode != TScsiServerModeSense6Req::KAllPages ||
   922     if (request.iPageCode != TScsiServerModeSense6Req::KAllPages ||
   953         request.iPageControl == TScsiServerModeSense6Req::EChangeableValues)
   923         request.iPageControl == TScsiServerModeSense6Req::EChangeableValues)
   954 		{
   924         {
   955 		__PRINT(_L("TSenseInfo::EIllegalRequest,TSenseInfo::EInvalidFieldInCdb"));
   925         __PRINT(_L("TSenseInfo::EIllegalRequest,TSenseInfo::EInvalidFieldInCdb"));
   956 		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest,TSenseInfo::EInvalidFieldInCdb);
   926         iSenseInfo.SetSense(TSenseInfo::EIllegalRequest,TSenseInfo::EInvalidFieldInCdb);
   957 		return EFalse;
   927         return EFalse;
   958 		}
   928         }
   959 	if (request.iPageControl != TScsiServerModeSense6Req::EDefaultValues)
   929     if (request.iPageControl != TScsiServerModeSense6Req::EDefaultValues)
   960 		{
   930         {
   961 		//check if drive write protected
   931         //check if drive write protected
   962 		CMassStorageDrive* drive = GetCheckDrive();
   932         CMassStorageDrive* drive = GetCheckDrive();
   963 		if (drive == NULL)
   933         if (drive == NULL)
   964 			{
   934             {
   965 			__PRINT(_L("drive == null"));
   935             __PRINT(_L("drive == null"));
   966 			return EFalse;
   936             return EFalse;
   967 			}
   937             }
   968 
   938 
   969 #ifdef MSDC_TESTMODE
   939 #ifdef MSDC_TESTMODE
   970     if (iTestParser)
   940     if (iTestParser)
   971         {
   941         {
   972         response.SetWp(iTestParser->WriteProtect());
   942         response.SetWp(iTestParser->WriteProtect());
   976 #endif
   946 #endif
   977         }
   947         }
   978 
   948 
   979     response.Encode(iCommandBuf);
   949     response.Encode(iCommandBuf);
   980 
   950 
   981 	TPtrC8 writeBuf = iCommandBuf;
   951     TPtrC8 writeBuf = iCommandBuf;
   982 	iTransport->SetupDataIn(writeBuf);
   952     iTransport->SetupDataIn(writeBuf);
   983 	return iSenseInfo.SenseOk();
   953     return iSenseInfo.SenseOk();
   984 	}
   954     }