userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp
changeset 300 1d28c8722707
parent 127 e408fc570bb5
equal deleted inserted replaced
293:0659d0e1a03c 300:1d28c8722707
    18  @internalTechnology
    18  @internalTechnology
    19 */
    19 */
    20 
    20 
    21 #include <e32base.h>
    21 #include <e32base.h>
    22 
    22 
    23 #include "debug.h"
    23 #include "OstTraceDefinitions.h"
    24 #include "msdebug.h"
    24 #ifdef OST_TRACE_COMPILER_IN_USE
       
    25 #include "cscsiprotocolTraces.h"
       
    26 #endif
       
    27 
    25 #include "msctypes.h"
    28 #include "msctypes.h"
    26 #include "shared.h"
    29 #include "shared.h"
    27 #include "msgservice.h"
    30 #include "msgservice.h"
    28 
    31 
    29 #include "mtransport.h"
    32 #include "mtransport.h"
    51 @param aStatusPollingInterval The polling interval
    54 @param aStatusPollingInterval The polling interval
    52 @return CScsiProtocol* A reference to the
    55 @return CScsiProtocol* A reference to the
    53 */
    56 */
    54 CScsiProtocol* CScsiProtocol::NewL(TLun aLun, MTransport& aTransport)
    57 CScsiProtocol* CScsiProtocol::NewL(TLun aLun, MTransport& aTransport)
    55     {
    58     {
    56 	__MSFNSLOG
    59     CScsiProtocol* r = new (ELeave) CScsiProtocol(aTransport);
    57 	CScsiProtocol* r = new (ELeave) CScsiProtocol(aTransport);
    60 
    58 
    61     CleanupStack::PushL(r);
    59 	CleanupStack::PushL(r);
    62     r->ConstructL(aLun);
    60 	r->ConstructL(aLun);
    63     CleanupStack::Pop();
    61 	CleanupStack::Pop();
    64     return r;
    62 	return r;
       
    63     }
    65     }
    64 
    66 
    65 void CScsiProtocol::ConstructL(TLun aLun)
    67 void CScsiProtocol::ConstructL(TLun aLun)
    66     {
    68     {
    67 	__MSFNLOG
    69     // iState = EEntry;
    68 	// iState = EEntry;
       
    69     iFsm = CMassStorageFsm::NewL(*this);
    70     iFsm = CMassStorageFsm::NewL(*this);
    70 
    71 
    71     const TInt blockLength = 0x200;
    72     const TInt blockLength = 0x200;
    72 
    73 
    73     iHeadbuf.CreateL(blockLength);
    74     iHeadbuf.CreateL(blockLength);
    77 
    78 
    78 CScsiProtocol::CScsiProtocol(MTransport& aTransport)
    79 CScsiProtocol::CScsiProtocol(MTransport& aTransport)
    79 :   iSpcInterface(aTransport),
    80 :   iSpcInterface(aTransport),
    80     iSbcInterface(NULL)
    81     iSbcInterface(NULL)
    81     {
    82     {
    82 	__MSFNLOG
       
    83     }
    83     }
    84 
    84 
    85 
    85 
    86 CScsiProtocol::~CScsiProtocol()
    86 CScsiProtocol::~CScsiProtocol()
    87     {
    87     {
    88 	__MSFNLOG
       
    89     delete iFsm;
    88     delete iFsm;
    90     iHeadbuf.Close();
    89     iHeadbuf.Close();
    91     iTailbuf.Close();
    90     iTailbuf.Close();
    92     delete iSbcInterface;
    91     delete iSbcInterface;
    93     }
    92     }
    94 
    93 
    95 
    94 
    96 void CScsiProtocol::InitialiseUnitL()
    95 void CScsiProtocol::InitialiseUnitL()
    97     {
    96     {
    98 	__MSFNLOG
       
    99     iState = EDisconnected;
    97     iState = EDisconnected;
   100 
    98 
   101 	// A device may take time to mount the media. If the device fails attempt to
    99     // A device may take time to mount the media. If the device fails attempt to
   102 	// retry the connection for a number of seconds
   100     // retry the connection for a number of seconds
   103     TInt retryCounter = 20;
   101     TInt retryCounter = 20;
   104     do
   102     do
   105         {
   103         {
   106         retryCounter--;
   104         retryCounter--;
   107         TInt err = iFsm->ConnectLogicalUnitL();
   105         TInt err = iFsm->ConnectLogicalUnitL();
   115             break;
   113             break;
   116             }
   114             }
   117         User::After(1000 * 200);    // 200 mS
   115         User::After(1000 * 200);    // 200 mS
   118         }
   116         }
   119     while (retryCounter);
   117     while (retryCounter);
   120 	}
   118     }
   121 
   119 
   122 
   120 
   123 void CScsiProtocol::UninitialiseUnitL()
   121 void CScsiProtocol::UninitialiseUnitL()
   124     {
   122     {
   125 	__MSFNLOG
       
   126     iFsm->DisconnectLogicalUnitL();
   123     iFsm->DisconnectLogicalUnitL();
   127     }
   124     }
   128 
   125 
   129 TBool CScsiProtocol::IsConnected()
   126 TBool CScsiProtocol::IsConnected()
   130     {
   127     {
   131 	__MSFNLOG
   128     return (iState == EConnected)? ETrue : EFalse;
   132 	return (iState == EConnected)? ETrue : EFalse;
       
   133     }
   129     }
   134 
   130 
   135 void CScsiProtocol::ReadL(TPos aPos,
   131 void CScsiProtocol::ReadL(TPos aPos,
   136                           TDes8& aBuf,
   132                           TDes8& aBuf,
   137                           TInt aLength)
   133                           TInt aLength)
   138     {
   134     {
   139 	__MSFNLOG
       
   140 
   135 
   141     if (!iSbcInterface)
   136     if (!iSbcInterface)
   142         User::Leave(KErrNotSupported);
   137         User::Leave(KErrNotSupported);
   143 
   138 
   144     if(!IsConnected())
   139     if(!IsConnected())
   145 		User::Leave(KErrNotReady);
   140         User::Leave(KErrNotReady);
   146     iSbcInterface->iBlockTransfer.ReadL(*this, aPos, aLength, aBuf);
   141     iSbcInterface->iBlockTransfer.ReadL(*this, aPos, aLength, aBuf);
   147     }
   142     }
   148 
   143 
   149 
   144 
   150 void CScsiProtocol::BlockReadL(TPos aPos, TDes8& aCopybuf, TInt aLen)
   145 void CScsiProtocol::BlockReadL(TPos aPos, TDes8& aCopybuf, TInt aLen)
   151     {
   146     {
   152 	__MSFNLOG
       
   153     if (!iSbcInterface)
   147     if (!iSbcInterface)
   154         User::Leave(KErrNotSupported);
   148         User::Leave(KErrNotSupported);
   155 
   149 
   156 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   150     __ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   157                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   151                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   158 
   152 
   159     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   153     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   160     TInt len = aLen;
   154     TInt len = aLen;
   161 
   155 
   164     if (I64HIGH(lba))
   158     if (I64HIGH(lba))
   165         {
   159         {
   166         User::LeaveIfError(KErrOverflow);
   160         User::LeaveIfError(KErrOverflow);
   167         }
   161         }
   168 
   162 
   169 	TInt err = iSbcInterface->Read10L(I64LOW(lba), aCopybuf, len);
   163     TInt err = iSbcInterface->Read10L(I64LOW(lba), aCopybuf, len);
   170     if (err)
   164     if (err)
   171         {
   165         {
   172         __SCSIPRINT1(_L("READ(10) Err=%d"), err);
   166         OstTrace1(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_10,
       
   167                   "READ(10) Err=%d", err);
   173         User::LeaveIfError(DoCheckConditionL());
   168         User::LeaveIfError(DoCheckConditionL());
   174         }
   169         }
   175 
   170 
   176     // handle residue
   171     // handle residue
   177     while (len != aLen)
   172     while (len != aLen)
   178         {
   173         {
   179         __SCSIPRINT2(_L("SCSI Read Residue 0x%x bytes read (0x%x)"), len, aLen);
   174         OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_11,
   180         __SCSIPRINT2(_L("Pos=0x%lx Len=0x%x"), aPos, aLen);
   175                   "SCSI Read Residue 0x%x bytes read (0x%x)", len, aLen);
       
   176         OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_12,
       
   177                   "Pos=0x%lx Len=0x%x", aPos, aLen);
   181 
   178 
   182         // read next block
   179         // read next block
   183 
   180 
   184         // full blocks read in bytes
   181         // full blocks read in bytes
   185         TInt bytesRead = len/blockLen * blockLen;
   182         TInt bytesRead = len/blockLen * blockLen;
   186         aPos += bytesRead;
   183         aPos += bytesRead;
   187         aLen -= bytesRead;
   184         aLen -= bytesRead;
   188         len = aLen;
   185         len = aLen;
   189 
   186 
   190         __SCSIPRINT3(_L("New Pos=0x%lx Len=0x%x (bytes read = %x)"),
   187         OstTraceExt3(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_13,
   191                      aPos, aLen, bytesRead);
   188                      "New Pos=0x%lx Len=0x%x (bytes read = %x)", aPos, aLen, bytesRead);
   192 
   189 
   193         aCopybuf.SetLength(bytesRead);
   190         aCopybuf.SetLength(bytesRead);
   194 
   191 
   195         // read rest of the block
   192         // read rest of the block
   196         TInt err = iSbcInterface->Read10L(aPos/blockLen, aCopybuf, len);
   193         TInt err = iSbcInterface->Read10L(aPos/blockLen, aCopybuf, len);
   204 
   201 
   205 void CScsiProtocol::WriteL(TPos aPosition,
   202 void CScsiProtocol::WriteL(TPos aPosition,
   206                            TDesC8& aBuf,
   203                            TDesC8& aBuf,
   207                            TInt aLength)
   204                            TInt aLength)
   208     {
   205     {
   209 	__MSFNLOG
       
   210     if (!iSbcInterface)
   206     if (!iSbcInterface)
   211         User::Leave(KErrNotSupported);
   207         User::Leave(KErrNotSupported);
   212 
   208 
   213     if(!IsConnected())
   209     if(!IsConnected())
   214 		User::Leave(KErrNotReady);
   210         User::Leave(KErrNotReady);
   215     iSbcInterface->iBlockTransfer.WriteL(*this, aPosition, aLength, aBuf);
   211     iSbcInterface->iBlockTransfer.WriteL(*this, aPosition, aLength, aBuf);
   216     }
   212     }
   217 
   213 
   218 
   214 
   219 void CScsiProtocol::BlockWriteL(TPos aPos, TDesC8& aCopybuf, TUint aOffset, TInt aLen)
   215 void CScsiProtocol::BlockWriteL(TPos aPos, TDesC8& aCopybuf, TUint aOffset, TInt aLen)
   220     {
   216     {
   221 	__MSFNLOG
       
   222     if (!iSbcInterface)
   217     if (!iSbcInterface)
   223         User::Leave(KErrNotSupported);
   218         User::Leave(KErrNotSupported);
   224 
   219 
   225 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   220     __ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   226                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   221                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   227     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   222     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   228     TInt len = aLen;
   223     TInt len = aLen;
   229 	TInt err = iSbcInterface->Write10L(aPos/blockLen, aCopybuf, aOffset, len);
   224     TInt err = iSbcInterface->Write10L(aPos/blockLen, aCopybuf, aOffset, len);
   230     if (err)
   225     if (err)
   231         {
   226         {
   232         User::LeaveIfError(DoCheckConditionL());
   227         User::LeaveIfError(DoCheckConditionL());
   233         }
   228         }
   234 
   229 
   235     while (len != aLen)
   230     while (len != aLen)
   236         {
   231         {
   237         // handle residue
   232         // handle residue
   238         __SCSIPRINT2(_L("SCSI Write Residue 0x%x bytes read (0x%x)"), len, aLen);
   233         OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_20,
   239         __SCSIPRINT2(_L("Pos=0x%lx Len=0x%x"), aPos, aLen);
   234                      "SCSI Write Residue 0x%x bytes read (0x%x)", len, aLen);
       
   235         OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_21,
       
   236                      "Pos=0x%lx Len=0x%x", aPos, aLen);
   240 
   237 
   241         // write next block
   238         // write next block
   242 
   239 
   243         // full blocks written in bytes
   240         // full blocks written in bytes
   244         TInt bytesWritten = len/blockLen * blockLen;
   241         TInt bytesWritten = len/blockLen * blockLen;
   245         aPos += bytesWritten;
   242         aPos += bytesWritten;
   246         aLen -= bytesWritten;
   243         aLen -= bytesWritten;
   247         len = aLen;
   244         len = aLen;
   248         __SCSIPRINT2(_L("New Pos=0x%lx Len=0x%x"), aPos, aLen);
   245         OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_22,
       
   246                      "New Pos=0x%lx Len=0x%x", aPos, aLen);
   249 
   247 
   250         TPtrC8 buf = aCopybuf.Mid(bytesWritten);
   248         TPtrC8 buf = aCopybuf.Mid(bytesWritten);
   251 
   249 
   252         // write rest of the block
   250         // write rest of the block
   253         TInt err = iSbcInterface->Write10L(aPos/blockLen, buf, aOffset, len);
   251         TInt err = iSbcInterface->Write10L(aPos/blockLen, buf, aOffset, len);
   259     }
   257     }
   260 
   258 
   261 
   259 
   262 void CScsiProtocol::GetCapacityL(TCapsInfo& aCapsInfo)
   260 void CScsiProtocol::GetCapacityL(TCapsInfo& aCapsInfo)
   263     {
   261     {
   264 	__MSFNLOG
       
   265     if (!IsConnected())
   262     if (!IsConnected())
   266         {
   263         {
   267         if (!DoScsiReadyCheckEventL())
   264         if (!DoScsiReadyCheckEventL())
   268             return;
   265             return;
   269         }
   266         }
   277         return;
   274         return;
   278         }
   275         }
   279 
   276 
   280     aCapsInfo.iMediaType = EMediaHardDisk;
   277     aCapsInfo.iMediaType = EMediaHardDisk;
   281 
   278 
   282 	TLba lastLba;
   279     TLba lastLba;
   283 	TUint32 blockLength;
   280     TUint32 blockLength;
   284 
   281 
   285     // Retry ReadCapacity10L if stalled
   282     // Retry ReadCapacity10L if stalled
   286     TInt stallCounter = 4;
   283     TInt stallCounter = 4;
   287     TInt err = KErrNone;
   284     TInt err = KErrNone;
   288     do
   285     do
   320             // ignore error if unsupported
   317             // ignore error if unsupported
   321             if (err != KErrUnknown)
   318             if (err != KErrUnknown)
   322                 {
   319                 {
   323                 User::LeaveIfError(err);
   320                 User::LeaveIfError(err);
   324                 }
   321                 }
   325             }           
   322             }
   326         }
   323         }
   327 
   324 
   328     aCapsInfo.iNumberOfBlocks = lastLba + 1;
   325     aCapsInfo.iNumberOfBlocks = lastLba + 1;
   329     aCapsInfo.iBlockLength = blockLength;
   326     aCapsInfo.iBlockLength = blockLength;
   330     aCapsInfo.iWriteProtect = iWriteProtect;
   327     aCapsInfo.iWriteProtect = iWriteProtect;
   331 
   328 
   332 	__SCSIPRINT3(_L("numBlock = x%x , blockLength = %x wp = %d"),
   329     OstTraceExt3(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_30,
   333                  lastLba + 1, blockLength, iWriteProtect);
   330                  "numBlock=x%x blockLength=x%x wp=%d",
       
   331                  (TUint32)(lastLba + 1), blockLength, (TInt32)iWriteProtect);
   334     }
   332     }
   335 
   333 
   336 
   334 
   337 /**
   335 /**
   338 Perform SCSI INQUIRY command. The function leaves if the device response is not
   336 Perform SCSI INQUIRY command. The function leaves if the device response is not
   341 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   339 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   342 device status error
   340 device status error
   343 */
   341 */
   344 TInt CScsiProtocol::MsInquiryL()
   342 TInt CScsiProtocol::MsInquiryL()
   345     {
   343     {
   346 	__MSFNLOG
       
   347     ResetSbc();
   344     ResetSbc();
   348 
   345 
   349    /**
   346    /**
   350     INQUIRY
   347     INQUIRY
   351    */
   348    */
   365         // KErrCommandFailed
   362         // KErrCommandFailed
   366         return err;
   363         return err;
   367         }
   364         }
   368 
   365 
   369     // print reponse
   366     // print reponse
   370     __TESTREPORT1(_L("RMB = %d"), info.iRemovable);
   367     OstTrace1(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_40,
   371     __TESTREPORT2(_L("PERIPHERAL DEVICE TYPE = %d PQ = %d"),
   368               "RMB = %d", info.iRemovable);
   372                  info.iPeripheralDeviceType,
   369     OstTraceExt2(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_41,
   373                  info.iPeripheralQualifier);
   370               "PERIPHERAL DEVICE TYPE = %d PQ = %d",
   374     __TESTREPORT1(_L("VERSION = %d"), info.iVersion);
   371               info.iPeripheralDeviceType,
   375     __TESTREPORT1(_L("RESPONSE DATA FORMAT = %d"), info.iResponseDataFormat);
   372               info.iPeripheralQualifier);
   376     __TESTREPORT3(_L("VENDOR ID %S PRODUCT ID %S REV %S"),
   373     OstTrace1(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_42,
   377                  &info.iIdentification.iVendorId,
   374               "VERSION = %d", info.iVersion);
   378                  &info.iIdentification.iProductId,
   375     OstTrace1(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_43,
   379                  &info.iIdentification.iProductRev);
   376               "RESPONSE DATA FORMAT = %d",
       
   377               info.iResponseDataFormat);
       
   378 
       
   379     OstTraceData(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_440,
       
   380               "VENDOR ID %s",
       
   381               info.iIdentification.iVendorId.Ptr(), info.iIdentification.iVendorId.Size() * 2);
       
   382     OstTraceData(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_441,
       
   383               "PRODUCT ID %s",
       
   384               info.iIdentification.iProductId.Ptr(), info.iIdentification.iProductId.Size()  * 2);
       
   385     OstTraceData(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_442,
       
   386               "REV %s",
       
   387               info.iIdentification.iProductRev.Ptr(), info.iIdentification.iProductRev.Size() * 2);
   380 
   388 
   381     if (info.iPeripheralQualifier != 0 && info.iPeripheralQualifier != 1)
   389     if (info.iPeripheralQualifier != 0 && info.iPeripheralQualifier != 1)
   382         {
   390         {
   383         __HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]"))
   391         OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, CSCSIPROTOCOL_45,
       
   392                   "Peripheral Qualifier[Unknown device type]");
   384         err = KErrUnknown;
   393         err = KErrUnknown;
   385         }
   394         }
   386     else if (info.iPeripheralDeviceType == 0)
   395     else if (info.iPeripheralDeviceType == 0)
   387         {
   396         {
   388         // SCSI SBC Direct access device
   397         // SCSI SBC Direct access device
   389         iRemovableMedia = info.iRemovable;
   398         iRemovableMedia = info.iRemovable;
   390     
   399 
   391         // SCSI Block device
   400         // SCSI Block device
   392         iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
   401         iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
   393         iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
   402         iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
   394         err = KErrNone;
   403         err = KErrNone;
   395         }
   404         }
   396     else if (info.iPeripheralDeviceType == 5)
   405     else if (info.iPeripheralDeviceType == 5)
   397         {
   406         {
   398         // SCSI MMC-2 CD-ROM device
   407         // SCSI MMC-2 CD-ROM device
   399         __HOSTPRINT(_L("Peripheral Device Type[CD-ROM]"))
   408         OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, CSCSIPROTOCOL_46,
       
   409                   "Peripheral Device Type[CD-ROM]");
   400         iRemovableMedia = info.iRemovable;
   410         iRemovableMedia = info.iRemovable;
   401 
   411 
   402         // MMC-2 is not supported. A SCSI interface call will return 
   412         // MMC-2 is not supported. A SCSI interface call will return
   403         // KErrNotSupported. If SCSI support is extended in future then
   413         // KErrNotSupported. If SCSI support is extended in future then
   404         // TSbcInterface class should be replaced with a proper interface class.
   414         // TSbcInterface class should be replaced with a proper interface class.
   405         iSbcInterface = NULL;
   415         iSbcInterface = NULL;
   406         err = KErrNone;
   416         err = KErrNone;
   407         }
   417         }
   408     else
   418     else
   409         {
   419         {
   410         __HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]"))
   420         OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, CSCSIPROTOCOL_47,
   411         err = KErrUnknown;    
   421                   "Peripheral Device Type[Unsupported device type]");
       
   422         err = KErrUnknown;
   412         }
   423         }
   413 
   424 
   414     return err;
   425     return err;
   415     }
   426     }
   416 
   427 
   422 @return TInt KErrNone if successful or otherwise KErrCommandFailed to indicate a
   433 @return TInt KErrNone if successful or otherwise KErrCommandFailed to indicate a
   423 device status error
   434 device status error
   424 */
   435 */
   425 TInt CScsiProtocol::MsTestUnitReadyL()
   436 TInt CScsiProtocol::MsTestUnitReadyL()
   426     {
   437     {
   427 	__MSFNLOG
       
   428     /* TestUnitReady */
   438     /* TestUnitReady */
   429     return iSpcInterface.TestUnitReadyL();
   439     return iSpcInterface.TestUnitReadyL();
   430     }
   440     }
   431 
   441 
   432 
   442 
   441 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
   451 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
   442 device status error, KErrCommandStalled to indicate a device stall
   452 device status error, KErrCommandStalled to indicate a device stall
   443 */
   453 */
   444 TInt CScsiProtocol::MsReadCapacityL()
   454 TInt CScsiProtocol::MsReadCapacityL()
   445     {
   455     {
   446 	__MSFNLOG
       
   447     if (!iSbcInterface)
   456     if (!iSbcInterface)
   448         {
   457         {
   449         User::Leave(KErrNotSupported);
   458         User::Leave(KErrNotSupported);
   450         }
   459         }
   451 
   460 
   452     // READ CAPACITY
   461     // READ CAPACITY
   453     TUint32 blockSize;
   462     TUint32 blockSize;
   454     TUint32 lastLba;
   463     TUint32 lastLba;
   455     TInt err = iSbcInterface->ReadCapacity10L(lastLba, blockSize);
   464     TInt err = iSbcInterface->ReadCapacity10L(lastLba, blockSize);
   456 
   465 
   457     __TESTREPORT2(_L("CAPACITY: Block Size=0x%x Last LBA=0x%x"), blockSize, lastLba);
   466     OstTraceExt2(TRACE_SHOSTMASSSTORAGE_DEVICEREPORT, CSCSIPROTOCOL_50,
       
   467                  "CAPACITY: Block Size=0x%x Last LBA=0x%x", blockSize, lastLba);
   458     return err;
   468     return err;
   459     }
   469     }
   460 
   470 
   461 
   471 
   462 /**
   472 /**
   466 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
   476 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
   467 device status error, KErrCommandStalled to indicate a device stall
   477 device status error, KErrCommandStalled to indicate a device stall
   468 */
   478 */
   469 TInt CScsiProtocol::MsModeSense10L()
   479 TInt CScsiProtocol::MsModeSense10L()
   470     {
   480     {
   471 	__MSFNLOG
       
   472     if (!iSbcInterface)
   481     if (!iSbcInterface)
   473         User::Leave(KErrNotSupported);
   482         User::Leave(KErrNotSupported);
   474 
   483 
   475     TBool writeProtected;
   484     TBool writeProtected;
   476     TInt err = iSbcInterface->ModeSense10L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   485     TInt err = iSbcInterface->ModeSense10L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   490 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
   499 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
   491 device status error, KErrCommandStalled to indicate a device stall
   500 device status error, KErrCommandStalled to indicate a device stall
   492 */
   501 */
   493 TInt CScsiProtocol::MsModeSense6L()
   502 TInt CScsiProtocol::MsModeSense6L()
   494     {
   503     {
   495 	__MSFNLOG
       
   496     if (!iSbcInterface)
   504     if (!iSbcInterface)
   497         User::Leave(KErrNotSupported);
   505         User::Leave(KErrNotSupported);
   498 
   506 
   499     TBool writeProtected;
   507     TBool writeProtected;
   500     TInt err = iSbcInterface->ModeSense6L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   508     TInt err = iSbcInterface->ModeSense6L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   514 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   522 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   515 device status error
   523 device status error
   516 */
   524 */
   517 TInt CScsiProtocol::MsStartStopUnitL(TBool aStart)
   525 TInt CScsiProtocol::MsStartStopUnitL(TBool aStart)
   518     {
   526     {
   519 	__MSFNLOG
       
   520     if (!iSbcInterface)
   527     if (!iSbcInterface)
   521         User::Leave(KErrNotSupported);
   528         User::Leave(KErrNotSupported);
   522 
   529 
   523     return iSbcInterface->StartStopUnitL(aStart);
   530     return iSbcInterface->StartStopUnitL(aStart);
   524     }
   531     }
   531 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   538 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   532 device status error
   539 device status error
   533 */
   540 */
   534 TInt CScsiProtocol::MsPreventAllowMediaRemovalL(TBool aPrevent)
   541 TInt CScsiProtocol::MsPreventAllowMediaRemovalL(TBool aPrevent)
   535     {
   542     {
   536 	__MSFNLOG
       
   537     return iSpcInterface.PreventAllowMediumRemovalL(aPrevent);
   543     return iSpcInterface.PreventAllowMediumRemovalL(aPrevent);
   538     }
   544     }
   539 
   545 
   540 
   546 
   541 TInt CScsiProtocol::DoCheckConditionL()
   547 TInt CScsiProtocol::DoCheckConditionL()
   542     {
   548     {
   543 	__MSFNLOG
       
   544     User::LeaveIfError(MsRequestSenseL());
   549     User::LeaveIfError(MsRequestSenseL());
   545 
   550 
   546     TInt err;
   551     TInt err;
   547 
   552 
   548     // Check if init is needed
   553     // Check if init is needed
   549     if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady &&
   554     if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady &&
   550         iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady &&
   555         iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady &&
   551         iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired)
   556         iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired)
   552         {
   557         {
   553 		if (iSbcInterface)
   558         if (iSbcInterface)
   554 			{
   559             {
   555 	        // start unit
   560             // start unit
   556 			err = iSbcInterface->StartStopUnitL(ETrue);
   561             err = iSbcInterface->StartStopUnitL(ETrue);
   557 	        if (err)
   562             if (err)
   558 		        {
   563                 {
   559 			    User::LeaveIfError(MsRequestSenseL());
   564                 User::LeaveIfError(MsRequestSenseL());
   560 				}			
   565                 }
   561 			}
   566             }
   562         }
   567         }
   563 
   568 
   564     err = GetSystemWideSenseError(iSenseInfo);
   569     err = GetSystemWideSenseError(iSenseInfo);
   565 
   570 
   566     TScsiState nextState = iState;
   571     TScsiState nextState = iState;
   580     if (nextState != iState)
   585     if (nextState != iState)
   581         {
   586         {
   582         iMediaChangeNotifier.DoNotifyL();
   587         iMediaChangeNotifier.DoNotifyL();
   583         iState = nextState;
   588         iState = nextState;
   584         }
   589         }
   585            
   590 
   586     return err;
   591     return err;
   587     }
   592     }
   588 
   593 
   589 
   594 
   590 /**
   595 /**
   628 KErrDisconnected could happen due to any of the following reasons:
   633 KErrDisconnected could happen due to any of the following reasons:
   629     1. The media was changed/removed - While this error is happening the file
   634     1. The media was changed/removed - While this error is happening the file
   630     extension will be notified setting the iChanged flag
   635     extension will be notified setting the iChanged flag
   631 */
   636 */
   632 TInt CScsiProtocol::GetSystemWideSenseError(const TSenseInfo& aSenseInfo)
   637 TInt CScsiProtocol::GetSystemWideSenseError(const TSenseInfo& aSenseInfo)
   633 	{
   638     {
   634 	__MSFNLOG
   639     TInt ret = KErrNone;
   635 	TInt ret = KErrNone;
   640     TInt additionalError = KErrNone;
   636 	TInt additionalError = KErrNone;
   641 
   637 
   642     switch(aSenseInfo.iSenseCode)
   638 	switch(aSenseInfo.iSenseCode)
   643         {
   639 		{
   644         case TSenseInfo::ENoSense:
   640 		case TSenseInfo::ENoSense:
   645         case TSenseInfo::ERecoveredError:
   641 		case TSenseInfo::ERecoveredError:
   646             ret = KErrNone;
   642 			ret = KErrNone;
   647             break;
   643 			break;
   648         case TSenseInfo::ENotReady:
   644 		case TSenseInfo::ENotReady:
       
   645             ret = KErrNotReady;
   649             ret = KErrNotReady;
   646 			additionalError = ProcessAsCodes(aSenseInfo);
   650             additionalError = ProcessAsCodes(aSenseInfo);
   647             if (additionalError != KErrNone)
   651             if (additionalError != KErrNone)
   648                 {
   652                 {
   649                 ret = additionalError;
   653                 ret = additionalError;
   650                 }
   654                 }
   651 			break;
   655             break;
   652 		case TSenseInfo::EMediumError:
   656         case TSenseInfo::EMediumError:
   653 			ret = KErrCorrupt;
   657             ret = KErrCorrupt;
   654 			additionalError = ProcessAsCodes(aSenseInfo);
   658             additionalError = ProcessAsCodes(aSenseInfo);
   655             if (additionalError != KErrNone)
   659             if (additionalError != KErrNone)
   656                 {
   660                 {
   657                 ret = additionalError;
   661                 ret = additionalError;
   658                 }
   662                 }
   659 			break;
   663             break;
   660 		case TSenseInfo::EUnitAttention:
   664         case TSenseInfo::EUnitAttention:
   661 			ret = KErrDisconnected;
   665             ret = KErrDisconnected;
   662 			break;
   666             break;
   663 		case TSenseInfo::EDataProtection:
   667         case TSenseInfo::EDataProtection:
   664 			ret = KErrAccessDenied;
   668             ret = KErrAccessDenied;
   665 			break;
   669             break;
   666 		case TSenseInfo::EIllegalRequest:
   670         case TSenseInfo::EIllegalRequest:
   667 		case TSenseInfo::EHardwareError:
   671         case TSenseInfo::EHardwareError:
   668 		case TSenseInfo::EBlankCheck:
   672         case TSenseInfo::EBlankCheck:
   669 		case TSenseInfo::EVendorSpecific:
   673         case TSenseInfo::EVendorSpecific:
   670 		case TSenseInfo::EMisCompare:
   674         case TSenseInfo::EMisCompare:
   671 			ret = KErrUnknown;
   675             ret = KErrUnknown;
   672 			break;
   676             break;
   673 		case TSenseInfo::ECopyAborted:
   677         case TSenseInfo::ECopyAborted:
   674 		case TSenseInfo::EAbortedCommand:
   678         case TSenseInfo::EAbortedCommand:
   675 			ret = KErrAbort;
   679             ret = KErrAbort;
   676 			break;
   680             break;
   677 		case TSenseInfo::EDataOverflow:
   681         case TSenseInfo::EDataOverflow:
   678 			ret = KErrOverflow;
   682             ret = KErrOverflow;
   679 			break;
   683             break;
   680 		default:
   684         default:
   681 			ret = KErrUnknown;
   685             ret = KErrUnknown;
   682 			break;
   686             break;
   683 		}
   687         }
   684 
   688 
   685 	return ret;
   689     return ret;
   686 	}
   690     }
   687 
   691 
   688 
   692 
   689 TInt CScsiProtocol::ProcessAsCodes(const TSenseInfo& aSenseInfo)
   693 TInt CScsiProtocol::ProcessAsCodes(const TSenseInfo& aSenseInfo)
   690     {
   694     {
   691 	__MSFNLOG
   695     TInt ret = KErrNone;
   692 	TInt ret = KErrNone;
   696 
   693 
   697     switch(aSenseInfo.iAdditional)
   694 	switch(aSenseInfo.iAdditional)
   698         {
   695 		{
       
   696         case TSenseInfo::EAscLogicalUnitNotReady:
   699         case TSenseInfo::EAscLogicalUnitNotReady:
   697 		case TSenseInfo::EMediaNotPresent:
   700         case TSenseInfo::EMediaNotPresent:
   698             ret = KErrNotReady;
   701             ret = KErrNotReady;
   699 			break;
   702             break;
   700 
   703 
   701 		case TSenseInfo::ELbaOutOfRange:
   704         case TSenseInfo::ELbaOutOfRange:
   702 			ret = KErrOverflow;
   705             ret = KErrOverflow;
   703 			break;
   706             break;
   704 
   707 
   705 		case TSenseInfo::EWriteProtected:
   708         case TSenseInfo::EWriteProtected:
   706 			ret = KErrAccessDenied;
   709             ret = KErrAccessDenied;
   707 			break;
   710             break;
   708 
   711 
   709 		case TSenseInfo::ENotReadyToReadyChange:
   712         case TSenseInfo::ENotReadyToReadyChange:
   710 			ret = KErrNone;
   713             ret = KErrNone;
   711 			break;
   714             break;
   712 
   715 
   713 		case TSenseInfo::EAscLogicalUnitDoesNotRespondToSelection:
   716         case TSenseInfo::EAscLogicalUnitDoesNotRespondToSelection:
   714 		case TSenseInfo::EInvalidCmdCode:
   717         case TSenseInfo::EInvalidCmdCode:
   715 		case TSenseInfo::EInvalidFieldInCdb:
   718         case TSenseInfo::EInvalidFieldInCdb:
   716 		case TSenseInfo::ELuNotSupported:
   719         case TSenseInfo::ELuNotSupported:
   717         case TSenseInfo::EInsufficientRes:
   720         case TSenseInfo::EInsufficientRes:
   718             ret = KErrUnknown;
   721             ret = KErrUnknown;
   719             break;
   722             break;
   720 		default:
   723         default:
   721 			ret = KErrNone;
   724             ret = KErrNone;
   722 			break;
   725             break;
   723 		}
   726         }
   724 	return ret;
   727     return ret;
   725 	}
   728     }
   726 
   729 
   727 
   730 
   728 /**
   731 /**
   729 Perform SCSI REQUEST SENSE command.  The function leaves if the device response
   732 Perform SCSI REQUEST SENSE command.  The function leaves if the device response
   730 is not compliant with the protocol standard.
   733 is not compliant with the protocol standard.
   732 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   735 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
   733 device status error
   736 device status error
   734 */
   737 */
   735 TInt CScsiProtocol::MsRequestSenseL()
   738 TInt CScsiProtocol::MsRequestSenseL()
   736     {
   739     {
   737 	__MSFNLOG
       
   738     return iSpcInterface.RequestSenseL(iSenseInfo) ? KErrCommandFailed : KErrNone;
   740     return iSpcInterface.RequestSenseL(iSenseInfo) ? KErrCommandFailed : KErrNone;
   739 	}
   741     }
   740 
   742 
   741 
   743 
   742 void CScsiProtocol::CreateSbcInterfaceL(TUint32 aBlockLen, TUint32 aLastLba)
   744 void CScsiProtocol::CreateSbcInterfaceL(TUint32 aBlockLen, TUint32 aLastLba)
   743     {
   745     {
   744 	__MSFNLOG
       
   745     // SCSI Block device
   746     // SCSI Block device
   746     ASSERT(iSbcInterface == NULL);
   747     ASSERT(iSbcInterface == NULL);
   747     iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
   748     iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
   748     iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
   749     iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
   749     iSbcInterface->SetCapacityL(aBlockLen, aLastLba);
   750     iSbcInterface->SetCapacityL(aBlockLen, aLastLba);
   750     }
   751     }
   751 
   752 
   752 
   753 
   753 void CScsiProtocol::ResetSbc()
   754 void CScsiProtocol::ResetSbc()
   754     {
   755     {
   755 	__MSFNLOG
       
   756     if (iSbcInterface)
   756     if (iSbcInterface)
   757         {
   757         {
   758         delete iSbcInterface;
   758         delete iSbcInterface;
   759         iSbcInterface = NULL;
   759         iSbcInterface = NULL;
   760         }
   760         }
   761     }
   761     }
   762 
   762 
   763 
   763 
   764 void CScsiProtocol::NotifyChange(const RMessage2& aMessage)
   764 void CScsiProtocol::NotifyChange(const RMessage2& aMessage)
   765 	{
   765     {
   766     __MSFNLOG
       
   767     iMediaChangeNotifier.Register(aMessage);
   766     iMediaChangeNotifier.Register(aMessage);
   768 	}
   767     }
   769 
   768 
   770 
   769 
   771 void CScsiProtocol::ForceCompleteNotifyChangeL()
   770 void CScsiProtocol::ForceCompleteNotifyChangeL()
   772 	{
   771     {
   773     __MSFNLOG
       
   774     iMediaChangeNotifier.DoNotifyL();
   772     iMediaChangeNotifier.DoNotifyL();
   775 	}
   773     }
   776 
   774 
   777 
   775 
   778 void CScsiProtocol::CancelChangeNotifierL()
   776 void CScsiProtocol::CancelChangeNotifierL()
   779 	{
   777     {
   780     __MSFNLOG
       
   781     iMediaChangeNotifier.DoCancelL();
   778     iMediaChangeNotifier.DoCancelL();
   782 	}
   779     }
   783 
   780 
   784 
   781 
   785 void CScsiProtocol::SuspendL()
   782 void CScsiProtocol::SuspendL()
   786 	{
   783     {
   787     __MSFNLOG
       
   788     if (iFsm->StartStopUnitRequired())
   784     if (iFsm->StartStopUnitRequired())
   789         {
   785         {
   790         iSbcInterface->StartStopUnitL(EFalse);
   786         iSbcInterface->StartStopUnitL(EFalse);
   791         }
   787         }
   792 	}
   788     }
   793 
   789 
   794 void CScsiProtocol::ResumeL()
   790 void CScsiProtocol::ResumeL()
   795 	{
   791     {
   796     __MSFNLOG
       
   797     if (iFsm->StartStopUnitRequired())
   792     if (iFsm->StartStopUnitRequired())
   798         {
   793         {
   799         iSbcInterface->StartStopUnitL(ETrue);
   794         iSbcInterface->StartStopUnitL(ETrue);
   800         }
   795         }
   801 	}
   796     }
   802 
   797 
   803 
   798 
   804 TBool CScsiProtocol::DoScsiReadyCheckEventL()
   799 TBool CScsiProtocol::DoScsiReadyCheckEventL()
   805 	{
   800     {
   806     __MSFNLOG
   801     TInt err = KErrNone;
   807 	TInt err = KErrNone;
   802 
   808 
   803     if(iRemovableMedia || iState != EConnected)
   809 	if(iRemovableMedia || iState != EConnected)
   804         {
   810         {
   805         iFsm->SetStatusCheck();
   811 		iFsm->SetStatusCheck();
   806         TRAP(err, iFsm->ConnectLogicalUnitL());
   812 		TRAP(err, iFsm->ConnectLogicalUnitL());
   807         iFsm->ClearStatusCheck();
   813 		iFsm->ClearStatusCheck();
   808 
   814 
   809         User::LeaveIfError(err);
   815 		User::LeaveIfError(err);
   810         err = iFsm->IsConnected() ? KErrNone : KErrNotReady;
   816 		err = iFsm->IsConnected() ? KErrNone : KErrNotReady;
   811         }
   817         }
   812 
   818 
   813     if (iState == EConnected)
   819 	if (iState == EConnected)
   814         {
   820         {
   815         if (err != KErrNone)
   821 		if (err != KErrNone)
   816             {
   822 			{
   817             iState = EDisconnected;
   823 			iState = EDisconnected;
   818             OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_60,
   824             __SCSIPRINT(_L("** Disconnected Notification **"));
   819                       "** Disconnected Notification **");
   825             iMediaChangeNotifier.DoNotifyL();
   820             iMediaChangeNotifier.DoNotifyL();
   826 			}
   821             }
   827         }
   822         }
   828 	else
   823     else
   829         {
   824         {
   830 		if (err == KErrNone)
   825         if (err == KErrNone)
   831 			{
   826             {
   832 			iState = EConnected;
   827             iState = EConnected;
   833             __SCSIPRINT(_L("** Connected Notification **"));
   828             OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, CSCSIPROTOCOL_61,
       
   829                       "** Connected Notification **");
   834             iMediaChangeNotifier.DoNotifyL();
   830             iMediaChangeNotifier.DoNotifyL();
   835 			}
   831             }
   836         }
   832         }
   837     return err = KErrNone ? ETrue : EFalse;
   833     return err = KErrNone ? ETrue : EFalse;
   838 	}
   834     }
   839 
   835 
   840 
   836 
   841 RMediaChangeNotifier::RMediaChangeNotifier()
   837 RMediaChangeNotifier::RMediaChangeNotifier()
   842 :   iRegistered(EFalse)
   838 :   iRegistered(EFalse)
   843     {
   839     {
   844     __MSFNSLOG
       
   845     }
   840     }
   846 
   841 
   847 
   842 
   848 RMediaChangeNotifier::~RMediaChangeNotifier()
   843 RMediaChangeNotifier::~RMediaChangeNotifier()
   849     {
   844     {
   850     __MSFNSLOG
       
   851     if (iRegistered)
   845     if (iRegistered)
   852         iNotifier.Complete(KErrDisconnected);
   846         iNotifier.Complete(KErrDisconnected);
   853     }
   847     }
   854 
   848 
   855 /**
   849 /**
   857 
   851 
   858 @param aMessage The message to commplete the notification
   852 @param aMessage The message to commplete the notification
   859 */
   853 */
   860 void RMediaChangeNotifier::Register(const RMessage2& aMessage)
   854 void RMediaChangeNotifier::Register(const RMessage2& aMessage)
   861     {
   855     {
   862     __MSFNLOG
   856     iRegistered = ETrue;
   863 	iRegistered = ETrue;
   857     iNotifier = aMessage;
   864 	iNotifier = aMessage;
       
   865     }
   858     }
   866 
   859 
   867 
   860 
   868 void RMediaChangeNotifier::DoNotifyL()
   861 void RMediaChangeNotifier::DoNotifyL()
   869     {
   862     {
   870 	__MSFNLOG
   863     CompleteNotifierL(KErrNone);
   871 	CompleteNotifierL(KErrNone);
       
   872     }
   864     }
   873 
   865 
   874 void RMediaChangeNotifier::DoCancelL()
   866 void RMediaChangeNotifier::DoCancelL()
   875     {
   867     {
   876 	__MSFNLOG
   868     CompleteNotifierL(KErrCancel);
   877 	CompleteNotifierL(KErrCancel);
       
   878     }
   869     }
   879 
   870 
   880 void RMediaChangeNotifier::CompleteNotifierL(TInt aReason)
   871 void RMediaChangeNotifier::CompleteNotifierL(TInt aReason)
   881 	{
   872     {
   882     __MSFNLOG
   873     if (iRegistered)
   883 	if (iRegistered)
   874         {
   884         {
   875         TBool mediaChanged = ETrue;
   885 		TBool mediaChanged = ETrue;
   876         TPtrC8 pStatus((TUint8*)&mediaChanged,sizeof(TBool));
   886 		TPtrC8 pStatus((TUint8*)&mediaChanged,sizeof(TBool));
   877         iNotifier.WriteL(0,pStatus);
   887 		iNotifier.WriteL(0,pStatus);
   878         iNotifier.Complete(aReason);
   888 		iNotifier.Complete(aReason);
   879         iRegistered = EFalse;
   889 		iRegistered = EFalse;
   880         }
   890         }
   881     }
   891 	}