--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp Fri Apr 23 22:20:31 2010 +0100
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp Fri Apr 23 22:26:35 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
@@ -26,8 +26,6 @@
#include "shared.h"
#include "msgservice.h"
-#include "mscutils.h"
-
#include "mtransport.h"
#include "mprotocol.h"
#include "tscsiclientreq.h"
@@ -45,7 +43,6 @@
#include "usbmshostpanic.h"
-
/**
Create the CScsiProtocol object.
@@ -68,8 +65,8 @@
void CScsiProtocol::ConstructL(TLun aLun)
{
__MSFNLOG
+ // iState = EEntry;
iFsm = CMassStorageFsm::NewL(*this);
- iState = EDisconnected;
const TInt blockLength = 0x200;
@@ -99,6 +96,7 @@
void CScsiProtocol::InitialiseUnitL()
{
__MSFNLOG
+ iState = EDisconnected;
// A device may take time to mount the media. If the device fails attempt to
// retry the connection for a number of seconds
@@ -106,13 +104,16 @@
do
{
retryCounter--;
- iFsm->ConnectLogicalUnitL();
- iState = iFsm->IsConnected() ? EConnected: EDisconnected;
-
- if (iState == EConnected)
+ TInt err = iFsm->ConnectLogicalUnitL();
+ if (err == KErrNotSupported)
{
break;
}
+ if (iFsm->IsConnected())
+ {
+ iState = EConnected;
+ break;
+ }
User::After(1000 * 200); // 200 mS
}
while (retryCounter);
@@ -136,6 +137,10 @@
TInt aLength)
{
__MSFNLOG
+
+ if (!iSbcInterface)
+ User::Leave(KErrNotSupported);
+
if(!IsConnected())
User::Leave(KErrNotReady);
iSbcInterface->iBlockTransfer.ReadL(*this, aPos, aLength, aBuf);
@@ -145,6 +150,9 @@
void CScsiProtocol::BlockReadL(TPos aPos, TDes8& aCopybuf, TInt aLen)
{
__MSFNLOG
+ if (!iSbcInterface)
+ User::Leave(KErrNotSupported);
+
__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
User::Panic(KUsbMsHostPanicCat, EBlockDevice));
@@ -162,8 +170,7 @@
if (err)
{
__SCSIPRINT1(_L("READ(10) Err=%d"), err);
- DoCheckConditionL();
- User::LeaveIfError(KErrAbort);
+ User::LeaveIfError(DoCheckConditionL());
}
// handle residue
@@ -189,8 +196,7 @@
TInt err = iSbcInterface->Read10L(aPos/blockLen, aCopybuf, len);
if (err)
{
- DoCheckConditionL();
- User::LeaveIfError(KErrAbort);
+ User::LeaveIfError(DoCheckConditionL());
}
}
}
@@ -201,6 +207,9 @@
TInt aLength)
{
__MSFNLOG
+ if (!iSbcInterface)
+ User::Leave(KErrNotSupported);
+
if(!IsConnected())
User::Leave(KErrNotReady);
iSbcInterface->iBlockTransfer.WriteL(*this, aPosition, aLength, aBuf);
@@ -210,6 +219,9 @@
void CScsiProtocol::BlockWriteL(TPos aPos, TDesC8& aCopybuf, TUint aOffset, TInt aLen)
{
__MSFNLOG
+ if (!iSbcInterface)
+ User::Leave(KErrNotSupported);
+
__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
User::Panic(KUsbMsHostPanicCat, EBlockDevice));
const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
@@ -217,8 +229,7 @@
TInt err = iSbcInterface->Write10L(aPos/blockLen, aCopybuf, aOffset, len);
if (err)
{
- DoCheckConditionL();
- User::LeaveIfError(KErrAbort);
+ User::LeaveIfError(DoCheckConditionL());
}
while (len != aLen)
@@ -242,8 +253,7 @@
TInt err = iSbcInterface->Write10L(aPos/blockLen, buf, aOffset, len);
if (err)
{
- DoCheckConditionL();
- User::LeaveIfError(KErrAbort);
+ User::LeaveIfError(DoCheckConditionL());
}
}
}
@@ -257,6 +267,17 @@
DoScsiReadyCheckEventL();
}
+ if (!iSbcInterface)
+ {
+ aCapsInfo.iMediaType = EMediaCdRom;
+ aCapsInfo.iNumberOfBlocks = 0;
+ aCapsInfo.iBlockLength = 0;
+ aCapsInfo.iWriteProtect = ETrue;
+ return;
+ }
+
+ aCapsInfo.iMediaType = EMediaHardDisk;
+
TLba lastLba;
TUint32 blockLength;
@@ -268,15 +289,11 @@
err = iSbcInterface->ReadCapacity10L(lastLba, blockLength);
} while (err == KErrCommandStalled && stallCounter-- > 0);
-
if (err)
{
- if (err == KErrCommandFailed)
- {
- // Clear sense error
- DoCheckConditionL();
- }
- User::LeaveIfError(KErrAbort);
+ // DoCheckConditionL clears sense error
+ // Media not present will return KErrNotReady so leave here
+ User::LeaveIfError(DoCheckConditionL());
}
// update iWriteProtect
@@ -286,14 +303,24 @@
if (err == KErrCommandFailed)
{
// Clear sense error
- DoCheckConditionL();
+ err = DoCheckConditionL();
+ // ignore error if unsupported
+ if (err != KErrUnknown)
+ {
+ User::LeaveIfError(err);
+ }
}
err = MsModeSense6L();
if (err == KErrCommandFailed)
{
// Clear sense error
- DoCheckConditionL();
+ err = DoCheckConditionL();
+ // ignore error if unsupported
+ if (err != KErrUnknown)
+ {
+ User::LeaveIfError(err);
+ }
}
}
@@ -352,23 +379,38 @@
if (info.iPeripheralQualifier != 0 && info.iPeripheralQualifier != 1)
{
- __HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]\n"))
- return KErrUnknown;
+ __HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]"))
+ err = KErrUnknown;
+ }
+ else if (info.iPeripheralDeviceType == 0)
+ {
+ // SCSI SBC Direct access device
+ iRemovableMedia = info.iRemovable;
+
+ // SCSI Block device
+ iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
+ iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
+ err = KErrNone;
+ }
+ else if (info.iPeripheralDeviceType == 5)
+ {
+ // SCSI MMC-2 CD-ROM device
+ __HOSTPRINT(_L("Peripheral Device Type[CD-ROM]"))
+ iRemovableMedia = info.iRemovable;
+
+ // MMC-2 is not supported. A SCSI interface call will return
+ // KErrNotSupported. If SCSI support is extended in future then
+ // TSbcInterface class should be replaced with a proper interface class.
+ iSbcInterface = NULL;
+ err = KErrNone;
+ }
+ else
+ {
+ __HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]"))
+ err = KErrUnknown;
}
- if (info.iPeripheralDeviceType != 0)
- {
- __HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]\n"))
- return KErrUnknown;
- }
-
- iRemovableMedia = info.iRemovable;
-
- // SCSI Block device
- iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
- iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
-
- return KErrNone;
+ return err;
}
@@ -401,6 +443,11 @@
TInt CScsiProtocol::MsReadCapacityL()
{
__MSFNLOG
+ if (!iSbcInterface)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
// READ CAPACITY
TUint32 blockSize;
TUint32 lastLba;
@@ -421,6 +468,9 @@
TInt CScsiProtocol::MsModeSense10L()
{
__MSFNLOG
+ if (!iSbcInterface)
+ User::Leave(KErrNotSupported);
+
TBool writeProtected;
TInt err = iSbcInterface->ModeSense10L(TSbcClientInterface::EReturnAllModePages, writeProtected);
@@ -442,6 +492,9 @@
TInt CScsiProtocol::MsModeSense6L()
{
__MSFNLOG
+ if (!iSbcInterface)
+ User::Leave(KErrNotSupported);
+
TBool writeProtected;
TInt err = iSbcInterface->ModeSense6L(TSbcClientInterface::EReturnAllModePages, writeProtected);
@@ -463,6 +516,9 @@
TInt CScsiProtocol::MsStartStopUnitL(TBool aStart)
{
__MSFNLOG
+ if (!iSbcInterface)
+ User::Leave(KErrNotSupported);
+
return iSbcInterface->StartStopUnitL(aStart);
}
@@ -481,33 +537,52 @@
}
-void CScsiProtocol::DoCheckConditionL()
+TInt CScsiProtocol::DoCheckConditionL()
{
__MSFNLOG
User::LeaveIfError(MsRequestSenseL());
+ TInt err;
+
// Check if init is needed
if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady &&
iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady &&
iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired)
{
- // start unit
- TInt err = iSbcInterface->StartStopUnitL(ETrue);
-
- if (err)
- {
- User::LeaveIfError(MsRequestSenseL());
- }
-
+ if (iSbcInterface)
+ {
+ // start unit
+ err = iSbcInterface->StartStopUnitL(ETrue);
+ if (err)
+ {
+ User::LeaveIfError(MsRequestSenseL());
+ }
+ }
}
- TInt r = GetSystemWideSenseError(iSenseInfo);
+ err = GetSystemWideSenseError(iSenseInfo);
- if (((r == KErrNotReady) && (iState == EConnected)) ||
- r == KErrDisconnected)
- {
- CompleteNotifyChangeL();
+ TScsiState nextState = iState;
+ if (err == KErrDisconnected)
+ {
+ nextState = EDisconnected;
+ }
+ else if (err == KErrNotReady)
+ {
+ nextState = EMediaNotPresent;
}
+ else
+ {
+ // no state change;
+ }
+
+ if (nextState != iState)
+ {
+ iMediaChangeNotifier.DoNotifyL();
+ iState = nextState;
+ }
+
+ return err;
}
@@ -730,7 +805,7 @@
__MSFNLOG
TInt err = KErrNone;
- if(iFsm->IsRemovableMedia() || iState == EDisconnected)
+ if(iRemovableMedia || iState != EConnected)
{
iFsm->SetStatusCheck();
TRAP(err, iFsm->ConnectLogicalUnitL());
@@ -760,18 +835,6 @@
}
}
-void CScsiProtocol::CompleteNotifyChangeL()
- {
- __MSFNLOG
- if (!iFsm->IsStatusCheck())
- {
- if (iState == EConnected)
- {
- iState = EDisconnected;
- iMediaChangeNotifier.DoNotifyL();
- }
- }
- }
RMediaChangeNotifier::RMediaChangeNotifier()
: iRegistered(EFalse)