userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp
changeset 124 5802e2ce68ed
parent 90 947f0dc9f7a8
child 127 e408fc570bb5
equal deleted inserted replaced
123:fc55edbf3919 124:5802e2ce68ed
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2008-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".
    24 #include "msdebug.h"
    24 #include "msdebug.h"
    25 #include "msctypes.h"
    25 #include "msctypes.h"
    26 #include "shared.h"
    26 #include "shared.h"
    27 #include "msgservice.h"
    27 #include "msgservice.h"
    28 
    28 
    29 #include "mscutils.h"
       
    30 
       
    31 #include "mtransport.h"
    29 #include "mtransport.h"
    32 #include "mprotocol.h"
    30 #include "mprotocol.h"
    33 #include "tscsiclientreq.h"
    31 #include "tscsiclientreq.h"
    34 #include "tscsiprimarycmds.h"
    32 #include "tscsiprimarycmds.h"
    35 #include "tscsiblockcmds.h"
    33 #include "tscsiblockcmds.h"
    43 #include "cscsiprotocol.h"
    41 #include "cscsiprotocol.h"
    44 
    42 
    45 #include "usbmshostpanic.h"
    43 #include "usbmshostpanic.h"
    46 
    44 
    47 
    45 
    48 
       
    49 /**
    46 /**
    50 Create the CScsiProtocol object.
    47 Create the CScsiProtocol object.
    51 
    48 
    52 @param aLun The LUN for the device represented by this object
    49 @param aLun The LUN for the device represented by this object
    53 @param aTransport The transport interface
    50 @param aTransport The transport interface
    66     }
    63     }
    67 
    64 
    68 void CScsiProtocol::ConstructL(TLun aLun)
    65 void CScsiProtocol::ConstructL(TLun aLun)
    69     {
    66     {
    70 	__MSFNLOG
    67 	__MSFNLOG
       
    68 	// iState = EEntry;
    71     iFsm = CMassStorageFsm::NewL(*this);
    69     iFsm = CMassStorageFsm::NewL(*this);
    72 	iState = EDisconnected;
       
    73 
    70 
    74     const TInt blockLength = 0x200;
    71     const TInt blockLength = 0x200;
    75 
    72 
    76     iHeadbuf.CreateL(blockLength);
    73     iHeadbuf.CreateL(blockLength);
    77     iTailbuf.CreateL(blockLength);
    74     iTailbuf.CreateL(blockLength);
    97 
    94 
    98 
    95 
    99 void CScsiProtocol::InitialiseUnitL()
    96 void CScsiProtocol::InitialiseUnitL()
   100     {
    97     {
   101 	__MSFNLOG
    98 	__MSFNLOG
       
    99     iState = EDisconnected;
   102 
   100 
   103 	// A device may take time to mount the media. If the device fails attempt to
   101 	// A device may take time to mount the media. If the device fails attempt to
   104 	// retry the connection for a number of seconds
   102 	// retry the connection for a number of seconds
   105     TInt retryCounter = 20;
   103     TInt retryCounter = 20;
   106     do
   104     do
   107         {
   105         {
   108         retryCounter--;
   106         retryCounter--;
   109         iFsm->ConnectLogicalUnitL();
   107         TInt err = iFsm->ConnectLogicalUnitL();
   110         iState = iFsm->IsConnected() ? EConnected: EDisconnected;
   108         if (err == KErrNotSupported)
   111 
       
   112         if (iState == EConnected)
       
   113             {
   109             {
   114             break;
   110             break;
   115             }
   111             }
       
   112         if (iFsm->IsConnected())
       
   113             {
       
   114             iState = EConnected;
       
   115             break;
       
   116             }
   116         User::After(1000 * 200);    // 200 mS
   117         User::After(1000 * 200);    // 200 mS
   117         }
   118         }
   118     while (retryCounter);
   119     while (retryCounter);
   119 	}
   120 	}
   120 
   121 
   134 void CScsiProtocol::ReadL(TPos aPos,
   135 void CScsiProtocol::ReadL(TPos aPos,
   135                           TDes8& aBuf,
   136                           TDes8& aBuf,
   136                           TInt aLength)
   137                           TInt aLength)
   137     {
   138     {
   138 	__MSFNLOG
   139 	__MSFNLOG
       
   140 
       
   141     if (!iSbcInterface)
       
   142         User::Leave(KErrNotSupported);
       
   143 
   139     if(!IsConnected())
   144     if(!IsConnected())
   140 		User::Leave(KErrNotReady);
   145 		User::Leave(KErrNotReady);
   141     iSbcInterface->iBlockTransfer.ReadL(*this, aPos, aLength, aBuf);
   146     iSbcInterface->iBlockTransfer.ReadL(*this, aPos, aLength, aBuf);
   142     }
   147     }
   143 
   148 
   144 
   149 
   145 void CScsiProtocol::BlockReadL(TPos aPos, TDes8& aCopybuf, TInt aLen)
   150 void CScsiProtocol::BlockReadL(TPos aPos, TDes8& aCopybuf, TInt aLen)
   146     {
   151     {
   147 	__MSFNLOG
   152 	__MSFNLOG
       
   153     if (!iSbcInterface)
       
   154         User::Leave(KErrNotSupported);
       
   155 
   148 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   156 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   149                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   157                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   150 
   158 
   151     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   159     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   152     TInt len = aLen;
   160     TInt len = aLen;
   160 
   168 
   161 	TInt err = iSbcInterface->Read10L(I64LOW(lba), aCopybuf, len);
   169 	TInt err = iSbcInterface->Read10L(I64LOW(lba), aCopybuf, len);
   162     if (err)
   170     if (err)
   163         {
   171         {
   164         __SCSIPRINT1(_L("READ(10) Err=%d"), err);
   172         __SCSIPRINT1(_L("READ(10) Err=%d"), err);
   165         DoCheckConditionL();
   173         User::LeaveIfError(DoCheckConditionL());
   166         User::LeaveIfError(KErrAbort);
       
   167         }
   174         }
   168 
   175 
   169     // handle residue
   176     // handle residue
   170     while (len != aLen)
   177     while (len != aLen)
   171         {
   178         {
   187 
   194 
   188         // read rest of the block
   195         // read rest of the block
   189         TInt err = iSbcInterface->Read10L(aPos/blockLen, aCopybuf, len);
   196         TInt err = iSbcInterface->Read10L(aPos/blockLen, aCopybuf, len);
   190         if (err)
   197         if (err)
   191             {
   198             {
   192             DoCheckConditionL();
   199             User::LeaveIfError(DoCheckConditionL());
   193             User::LeaveIfError(KErrAbort);
       
   194             }
   200             }
   195         }
   201         }
   196     }
   202     }
   197 
   203 
   198 
   204 
   199 void CScsiProtocol::WriteL(TPos aPosition,
   205 void CScsiProtocol::WriteL(TPos aPosition,
   200                            TDesC8& aBuf,
   206                            TDesC8& aBuf,
   201                            TInt aLength)
   207                            TInt aLength)
   202     {
   208     {
   203 	__MSFNLOG
   209 	__MSFNLOG
       
   210     if (!iSbcInterface)
       
   211         User::Leave(KErrNotSupported);
       
   212 
   204     if(!IsConnected())
   213     if(!IsConnected())
   205 		User::Leave(KErrNotReady);
   214 		User::Leave(KErrNotReady);
   206     iSbcInterface->iBlockTransfer.WriteL(*this, aPosition, aLength, aBuf);
   215     iSbcInterface->iBlockTransfer.WriteL(*this, aPosition, aLength, aBuf);
   207     }
   216     }
   208 
   217 
   209 
   218 
   210 void CScsiProtocol::BlockWriteL(TPos aPos, TDesC8& aCopybuf, TUint aOffset, TInt aLen)
   219 void CScsiProtocol::BlockWriteL(TPos aPos, TDesC8& aCopybuf, TUint aOffset, TInt aLen)
   211     {
   220     {
   212 	__MSFNLOG
   221 	__MSFNLOG
       
   222     if (!iSbcInterface)
       
   223         User::Leave(KErrNotSupported);
       
   224 
   213 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   225 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
   214                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   226                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
   215     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   227     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
   216     TInt len = aLen;
   228     TInt len = aLen;
   217 	TInt err = iSbcInterface->Write10L(aPos/blockLen, aCopybuf, aOffset, len);
   229 	TInt err = iSbcInterface->Write10L(aPos/blockLen, aCopybuf, aOffset, len);
   218     if (err)
   230     if (err)
   219         {
   231         {
   220         DoCheckConditionL();
   232         User::LeaveIfError(DoCheckConditionL());
   221         User::LeaveIfError(KErrAbort);
       
   222         }
   233         }
   223 
   234 
   224     while (len != aLen)
   235     while (len != aLen)
   225         {
   236         {
   226         // handle residue
   237         // handle residue
   240 
   251 
   241         // write rest of the block
   252         // write rest of the block
   242         TInt err = iSbcInterface->Write10L(aPos/blockLen, buf, aOffset, len);
   253         TInt err = iSbcInterface->Write10L(aPos/blockLen, buf, aOffset, len);
   243         if (err)
   254         if (err)
   244             {
   255             {
   245             DoCheckConditionL();
   256             User::LeaveIfError(DoCheckConditionL());
   246             User::LeaveIfError(KErrAbort);
       
   247             }
   257             }
   248         }
   258         }
   249     }
   259     }
   250 
   260 
   251 
   261 
   254 	__MSFNLOG
   264 	__MSFNLOG
   255     if (!IsConnected())
   265     if (!IsConnected())
   256         {
   266         {
   257         DoScsiReadyCheckEventL();
   267         DoScsiReadyCheckEventL();
   258         }
   268         }
       
   269 
       
   270     if (!iSbcInterface)
       
   271         {
       
   272         aCapsInfo.iMediaType = EMediaCdRom;
       
   273         aCapsInfo.iNumberOfBlocks = 0;
       
   274         aCapsInfo.iBlockLength = 0;
       
   275         aCapsInfo.iWriteProtect = ETrue;
       
   276         return;
       
   277         }
       
   278 
       
   279     aCapsInfo.iMediaType = EMediaHardDisk;
   259 
   280 
   260 	TLba lastLba;
   281 	TLba lastLba;
   261 	TUint32 blockLength;
   282 	TUint32 blockLength;
   262 
   283 
   263     // Retry ReadCapacity10L if stalled
   284     // Retry ReadCapacity10L if stalled
   266     do
   287     do
   267         {
   288         {
   268         err = iSbcInterface->ReadCapacity10L(lastLba, blockLength);
   289         err = iSbcInterface->ReadCapacity10L(lastLba, blockLength);
   269         } while (err == KErrCommandStalled && stallCounter-- > 0);
   290         } while (err == KErrCommandStalled && stallCounter-- > 0);
   270 
   291 
   271 
   292     if (err)
       
   293         {
       
   294         // DoCheckConditionL clears sense error
       
   295         // Media not present will return KErrNotReady so leave here
       
   296         User::LeaveIfError(DoCheckConditionL());
       
   297         }
       
   298 
       
   299     // update iWriteProtect
       
   300     err = MsModeSense10L();
   272     if (err)
   301     if (err)
   273         {
   302         {
   274         if (err == KErrCommandFailed)
   303         if (err == KErrCommandFailed)
   275             {
   304             {
   276             // Clear sense error
   305             // Clear sense error
   277             DoCheckConditionL();
   306             err = DoCheckConditionL();
   278             }
   307             // ignore error if unsupported
   279         User::LeaveIfError(KErrAbort);
   308             if (err != KErrUnknown)
   280         }
   309                 {
   281 
   310                 User::LeaveIfError(err);
   282     // update iWriteProtect
   311                 }
   283     err = MsModeSense10L();
       
   284     if (err)
       
   285         {
       
   286         if (err == KErrCommandFailed)
       
   287             {
       
   288             // Clear sense error
       
   289             DoCheckConditionL();
       
   290             }
   312             }
   291 
   313 
   292         err = MsModeSense6L();
   314         err = MsModeSense6L();
   293         if (err == KErrCommandFailed)
   315         if (err == KErrCommandFailed)
   294             {
   316             {
   295             // Clear sense error
   317             // Clear sense error
   296             DoCheckConditionL();
   318             err = DoCheckConditionL();
       
   319             // ignore error if unsupported
       
   320             if (err != KErrUnknown)
       
   321                 {
       
   322                 User::LeaveIfError(err);
       
   323                 }
   297             }           
   324             }           
   298         }
   325         }
   299 
   326 
   300     aCapsInfo.iNumberOfBlocks = lastLba + 1;
   327     aCapsInfo.iNumberOfBlocks = lastLba + 1;
   301     aCapsInfo.iBlockLength = blockLength;
   328     aCapsInfo.iBlockLength = blockLength;
   350                  &info.iIdentification.iProductId,
   377                  &info.iIdentification.iProductId,
   351                  &info.iIdentification.iProductRev);
   378                  &info.iIdentification.iProductRev);
   352 
   379 
   353     if (info.iPeripheralQualifier != 0 && info.iPeripheralQualifier != 1)
   380     if (info.iPeripheralQualifier != 0 && info.iPeripheralQualifier != 1)
   354         {
   381         {
   355         __HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]\n"))
   382         __HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]"))
   356         return KErrUnknown;
   383         err = KErrUnknown;
   357         }
   384         }
   358 
   385     else if (info.iPeripheralDeviceType == 0)
   359     if (info.iPeripheralDeviceType != 0)
   386         {
   360         {
   387         // SCSI SBC Direct access device
   361         __HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]\n"))
   388         iRemovableMedia = info.iRemovable;
   362         return KErrUnknown;
   389     
   363         }
   390         // SCSI Block device
   364 
   391         iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
   365     iRemovableMedia = info.iRemovable;
   392         iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
   366 
   393         err = KErrNone;
   367     // SCSI Block device
   394         }
   368     iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
   395     else if (info.iPeripheralDeviceType == 5)
   369     iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
   396         {
   370 
   397         // SCSI MMC-2 CD-ROM device
   371     return KErrNone;
   398         __HOSTPRINT(_L("Peripheral Device Type[CD-ROM]"))
       
   399         iRemovableMedia = info.iRemovable;
       
   400 
       
   401         // MMC-2 is not supported. A SCSI interface call will return 
       
   402         // KErrNotSupported. If SCSI support is extended in future then
       
   403         // TSbcInterface class should be replaced with a proper interface class.
       
   404         iSbcInterface = NULL;
       
   405         err = KErrNone;
       
   406         }
       
   407     else
       
   408         {
       
   409         __HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]"))
       
   410         err = KErrUnknown;    
       
   411         }
       
   412 
       
   413     return err;
   372     }
   414     }
   373 
   415 
   374 
   416 
   375 /**
   417 /**
   376 Perform SCSI TEST UNIT READY command. The function leaves if the device response
   418 Perform SCSI TEST UNIT READY command. The function leaves if the device response
   399 device status error, KErrCommandStalled to indicate a device stall
   441 device status error, KErrCommandStalled to indicate a device stall
   400 */
   442 */
   401 TInt CScsiProtocol::MsReadCapacityL()
   443 TInt CScsiProtocol::MsReadCapacityL()
   402     {
   444     {
   403 	__MSFNLOG
   445 	__MSFNLOG
       
   446     if (!iSbcInterface)
       
   447         {
       
   448         User::Leave(KErrNotSupported);
       
   449         }
       
   450 
   404     // READ CAPACITY
   451     // READ CAPACITY
   405     TUint32 blockSize;
   452     TUint32 blockSize;
   406     TUint32 lastLba;
   453     TUint32 lastLba;
   407     TInt err = iSbcInterface->ReadCapacity10L(lastLba, blockSize);
   454     TInt err = iSbcInterface->ReadCapacity10L(lastLba, blockSize);
   408 
   455 
   419 device status error, KErrCommandStalled to indicate a device stall
   466 device status error, KErrCommandStalled to indicate a device stall
   420 */
   467 */
   421 TInt CScsiProtocol::MsModeSense10L()
   468 TInt CScsiProtocol::MsModeSense10L()
   422     {
   469     {
   423 	__MSFNLOG
   470 	__MSFNLOG
       
   471     if (!iSbcInterface)
       
   472         User::Leave(KErrNotSupported);
       
   473 
   424     TBool writeProtected;
   474     TBool writeProtected;
   425     TInt err = iSbcInterface->ModeSense10L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   475     TInt err = iSbcInterface->ModeSense10L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   426 
   476 
   427     if (!err)
   477     if (!err)
   428         {
   478         {
   440 device status error, KErrCommandStalled to indicate a device stall
   490 device status error, KErrCommandStalled to indicate a device stall
   441 */
   491 */
   442 TInt CScsiProtocol::MsModeSense6L()
   492 TInt CScsiProtocol::MsModeSense6L()
   443     {
   493     {
   444 	__MSFNLOG
   494 	__MSFNLOG
       
   495     if (!iSbcInterface)
       
   496         User::Leave(KErrNotSupported);
       
   497 
   445     TBool writeProtected;
   498     TBool writeProtected;
   446     TInt err = iSbcInterface->ModeSense6L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   499     TInt err = iSbcInterface->ModeSense6L(TSbcClientInterface::EReturnAllModePages, writeProtected);
   447 
   500 
   448     if (!err)
   501     if (!err)
   449         {
   502         {
   461 device status error
   514 device status error
   462 */
   515 */
   463 TInt CScsiProtocol::MsStartStopUnitL(TBool aStart)
   516 TInt CScsiProtocol::MsStartStopUnitL(TBool aStart)
   464     {
   517     {
   465 	__MSFNLOG
   518 	__MSFNLOG
       
   519     if (!iSbcInterface)
       
   520         User::Leave(KErrNotSupported);
       
   521 
   466     return iSbcInterface->StartStopUnitL(aStart);
   522     return iSbcInterface->StartStopUnitL(aStart);
   467     }
   523     }
   468 
   524 
   469 
   525 
   470 /**
   526 /**
   479 	__MSFNLOG
   535 	__MSFNLOG
   480     return iSpcInterface.PreventAllowMediumRemovalL(aPrevent);
   536     return iSpcInterface.PreventAllowMediumRemovalL(aPrevent);
   481     }
   537     }
   482 
   538 
   483 
   539 
   484 void CScsiProtocol::DoCheckConditionL()
   540 TInt CScsiProtocol::DoCheckConditionL()
   485     {
   541     {
   486 	__MSFNLOG
   542 	__MSFNLOG
   487     User::LeaveIfError(MsRequestSenseL());
   543     User::LeaveIfError(MsRequestSenseL());
       
   544 
       
   545     TInt err;
   488 
   546 
   489     // Check if init is needed
   547     // Check if init is needed
   490     if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady &&
   548     if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady &&
   491         iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady &&
   549         iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady &&
   492         iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired)
   550         iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired)
   493         {
   551         {
   494         // start unit
   552 		if (iSbcInterface)
   495         TInt err = iSbcInterface->StartStopUnitL(ETrue);
   553 			{
   496 
   554 	        // start unit
   497         if (err)
   555 			err = iSbcInterface->StartStopUnitL(ETrue);
   498             {
   556 	        if (err)
   499             User::LeaveIfError(MsRequestSenseL());
   557 		        {
   500             }
   558 			    User::LeaveIfError(MsRequestSenseL());
   501 
   559 				}			
   502         }
   560 			}
   503 
   561         }
   504     TInt r = GetSystemWideSenseError(iSenseInfo);
   562 
   505 
   563     err = GetSystemWideSenseError(iSenseInfo);
   506     if (((r == KErrNotReady) && (iState == EConnected)) ||
   564 
   507         r == KErrDisconnected)
   565     TScsiState nextState = iState;
   508 	    {
   566     if (err == KErrDisconnected)
   509         CompleteNotifyChangeL();
   567         {
   510         }
   568         nextState = EDisconnected;
       
   569         }
       
   570     else if (err == KErrNotReady)
       
   571         {
       
   572         nextState = EMediaNotPresent;
       
   573         }
       
   574     else
       
   575         {
       
   576         // no state change;
       
   577         }
       
   578 
       
   579     if (nextState != iState)
       
   580         {
       
   581         iMediaChangeNotifier.DoNotifyL();
       
   582         iState = nextState;
       
   583         }
       
   584            
       
   585     return err;
   511     }
   586     }
   512 
   587 
   513 
   588 
   514 /**
   589 /**
   515 Map SCSI sense error to a system wide error code
   590 Map SCSI sense error to a system wide error code
   728 void CScsiProtocol::DoScsiReadyCheckEventL()
   803 void CScsiProtocol::DoScsiReadyCheckEventL()
   729 	{
   804 	{
   730     __MSFNLOG
   805     __MSFNLOG
   731 	TInt err = KErrNone;
   806 	TInt err = KErrNone;
   732 
   807 
   733 	if(iFsm->IsRemovableMedia() || iState == EDisconnected)
   808 	if(iRemovableMedia || iState != EConnected)
   734         {
   809         {
   735 		iFsm->SetStatusCheck();
   810 		iFsm->SetStatusCheck();
   736 		TRAP(err, iFsm->ConnectLogicalUnitL());
   811 		TRAP(err, iFsm->ConnectLogicalUnitL());
   737 		iFsm->ClearStatusCheck();
   812 		iFsm->ClearStatusCheck();
   738 
   813 
   758             iMediaChangeNotifier.DoNotifyL();
   833             iMediaChangeNotifier.DoNotifyL();
   759 			}
   834 			}
   760         }
   835         }
   761 	}
   836 	}
   762 
   837 
   763 void CScsiProtocol::CompleteNotifyChangeL()
       
   764 	{
       
   765     __MSFNLOG
       
   766     if (!iFsm->IsStatusCheck())
       
   767 		{
       
   768 		if (iState == EConnected)
       
   769 			{
       
   770 			iState = EDisconnected;
       
   771             iMediaChangeNotifier.DoNotifyL();
       
   772 			}
       
   773 		}
       
   774 	}
       
   775 
   838 
   776 RMediaChangeNotifier::RMediaChangeNotifier()
   839 RMediaChangeNotifier::RMediaChangeNotifier()
   777 :   iRegistered(EFalse)
   840 :   iRegistered(EFalse)
   778     {
   841     {
   779     __MSFNSLOG
   842     __MSFNSLOG