Revision: 201017 RCL_3
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 27 Apr 2010 18:02:57 +0300
branchRCL_3
changeset 24 41f0cfe18c80
parent 23 1df514389a47
child 26 c734af59ce98
Revision: 201017 Kit: 201017
kernel/eka/drivers/hcr/documents/HCR Design Model.eap
kernel/eka/drivers/usbcc/descriptors.cpp
kernel/eka/include/e32ver.h
kernel/eka/memmodel/epoc/flexible/mmu/mmu.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp
kernel/eka/release.txt
kernelhwsrv_info/doc_pub/base_how_to_64bit_file_server_client_porting_guide.doc
kernelhwsrv_info/doc_pub/base_how_to_64bit_file_server_file_system_plugin_porting_guide.doc
kernelhwsrv_info/doc_pub/base_how_to_align_partitions_to_media_block_boundaries_for_optimised_performance.doc
kernelhwsrv_info/doc_pub/base_how_to_armv7_cache_and_access_remapping_-_design.doc
kernelhwsrv_info/doc_pub/base_how_to_btrace.doc
kernelhwsrv_info/doc_pub/base_how_to_configure_platform_security_settings.doc
kernelhwsrv_info/doc_pub/base_how_to_crash_logging.doc
kernelhwsrv_info/doc_pub/base_how_to_debug_nonxip_problems.doc
kernelhwsrv_info/doc_pub/base_how_to_estart.doc
kernelhwsrv_info/doc_pub/base_how_to_file_caching.doc
kernelhwsrv_info/doc_pub/base_how_to_handle_sharing.doc
kernelhwsrv_info/doc_pub/base_how_to_impacts_of_demand_paging_on_kernel-side_code.doc
kernelhwsrv_info/doc_pub/base_how_to_ipc.doc
kernelhwsrv_info/doc_pub/base_how_to_message_queues.doc
kernelhwsrv_info/doc_pub/base_how_to_migrate_device_drivers_to_paging_environment.doc
kernelhwsrv_info/doc_pub/base_how_to_migrate_media_drivers_to_support_demand_paging.doc
kernelhwsrv_info/doc_pub/base_how_to_migrate_to_client-server_v2_apis.doc
kernelhwsrv_info/doc_pub/base_how_to_mmc_direct_physical_addressing.doc
kernelhwsrv_info/doc_pub/base_how_to_mmc_double_buffering.doc
kernelhwsrv_info/doc_pub/base_how_to_persisting_a_custom_restart_reason.doc
kernelhwsrv_info/doc_pub/base_how_to_port_emmc_controller.doc
kernelhwsrv_info/doc_pub/base_how_to_port_sdio_controller_supplement.doc
kernelhwsrv_info/doc_pub/base_how_to_publish_and_subscribe.doc
kernelhwsrv_info/doc_pub/base_how_to_share_file_handles.doc
kernelhwsrv_info/doc_pub/base_how_to_usb_client_porting_and_test.doc
kernelhwsrv_info/doc_pub/base_how_to_usb_mass_storage_app.doc
kernelhwsrv_info/doc_pub/base_how_to_usb_mass_storage_double_buffering.doc
kernelhwsrv_info/doc_pub/base_how_to_use_cfileman_test_framework.doc
kernelhwsrv_info/doc_pub/base_how_to_use_dma_for_sdio_data_transfers.doc
kernelhwsrv_info/doc_pub/base_how_to_use_t_fatcharsetconv_framework.doc
kernelhwsrv_info/doc_pub/base_how_to_vfp_support.doc
kernelhwsrv_info/doc_pub/base_migrating_device_drivers_dfc_q.doc
kernelhwsrv_info/doc_pub/base_migrating_kernel api preconditions checking.doc
kernelhwsrv_info/doc_pub/base_migrating_media_drivers_dma.doc
kernelhwsrv_info/doc_pub/base_smp_driver_migration_guide.doc
kernelhwsrv_info/doc_pub/base_smp_user_side_migration_guide.doc
kerneltest/e32test/mmu/t_cachechunk.cpp
kerneltest/e32test/resourceman/acctst/d_prmacctst.cpp
kerneltest/f32test/demandpaging/t_nandpaging.cpp
userlibandfileserver/fileserver/group/release.txt
userlibandfileserver/fileserver/inc/f32ver.h
userlibandfileserver/fileserver/shostmassstorage/client/debug.h
userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp
userlibandfileserver/fileserver/shostmassstorage/msproxy/hostusbmsproxy.cpp
userlibandfileserver/fileserver/shostmassstorage/server/controller/cusbhostmsdevice.cpp
userlibandfileserver/fileserver/shostmassstorage/server/controller/cusbhostmsdevicethread.cpp
userlibandfileserver/fileserver/shostmassstorage/server/controller/include/cusbhostmsdevice.h
userlibandfileserver/fileserver/shostmassstorage/server/controller/tlogicalunitlist.cpp
userlibandfileserver/fileserver/shostmassstorage/server/protocol/cmassstoragefsm.cpp
userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp
userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiprimarycmds.cpp
userlibandfileserver/fileserver/shostmassstorage/shared/shared.h
Binary file kernel/eka/drivers/hcr/documents/HCR Design Model.eap has changed
--- a/kernel/eka/drivers/usbcc/descriptors.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/kernel/eka/drivers/usbcc/descriptors.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -2093,8 +2093,8 @@
 		}
 	return iDescriptors[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
 	}
-
-
+	
+	
 //
 // Put the current Configuration or Other_Speed_Configuration descriptor + all the following
 // descriptors in the Ep0 Tx buffer.
@@ -2112,22 +2112,46 @@
 		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Descriptor %d requested but not available", aIndex));
 		return 0;
 		}
-	const TInt count = iDescriptors.Count();
+		
+	const TInt count = iDescriptors.Count();	
 	TInt copied = 0;
 	TUint8* buf = iEp0_TxBuf;
-	for (TInt i = aIndex; i < count; i++)
+	// pos == count is used so that otg descriptor is added to the end of returned descriptors
+	for (TInt pos = aIndex; pos < count + 1; pos++)
 		{
-		TUsbcDescriptorBase* const ptr = iDescriptors[i];
-		if ((aIndex == KDescPosition_OtherSpeedConfig) && (i == KDescPosition_Config))
+			
+		if ((aIndex == KDescPosition_OtherSpeedConfig) && (pos == KDescPosition_Config))
 			{
 			// Skip Config descriptor when returning Other_Speed_Config
 			continue;
 			}
-		if ((i == KDescPosition_Otg) && (iDescriptors[i] == NULL))
+			
+		if (pos == KDescPosition_Otg) 
 			{
-			__KTRACE_OPT(KUSB, Kern::Printf("  no OTG descriptor -> next"));
+			// Skip otg descriptor just now. add it when pos is count, so that OTG are added at the end
 			continue;
 			}
+						
+		TUsbcDescriptorBase* ptr = NULL;	
+		if (pos == count)
+			{
+				if (iDescriptors[KDescPosition_Otg] == NULL)
+					{
+					// Skip since there is no otg descriptor
+					__KTRACE_OPT(KUSB, Kern::Printf("  no otg descriptor"));
+					continue;				
+					}
+				else
+					{
+					// add otg to the end of returned descriptors
+					ptr = iDescriptors[KDescPosition_Otg];
+					}
+			}
+		else
+			{
+			ptr = iDescriptors[pos];
+			}
+
 		// We need to edit endpoint descriptors on the fly because we have only one copy
 		// of each and that copy has to contain different information, depending on the
 		// current speed and the type of descriptor requested.
@@ -2143,11 +2167,13 @@
 				ptr->UpdateFs();
 				}
 			}
+
 		__KTRACE_OPT(KUSB, Kern::Printf("  desc[%02d]: type = 0x%02x size = %d ",
-										i, ptr->Type(), ptr->Size()));
+										pos, ptr->Type(), ptr->Size()));				
 		const TInt size = ptr->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied);
 		if (size == 0)
 			{
+			
 			__KTRACE_OPT(KPANIC,
 						 Kern::Printf("  Error: No Tx buffer space to copy this descriptor -> exiting"));
 			break;
@@ -2161,6 +2187,8 @@
 			}
 		buf += size;
 		}
+		
+		
 	__KTRACE_OPT(KUSB, Kern::Printf("  copied %d bytes", copied));
 	return copied;
 	}
--- a/kernel/eka/include/e32ver.h	Wed Apr 14 17:22:59 2010 +0300
+++ b/kernel/eka/include/e32ver.h	Tue Apr 27 18:02:57 2010 +0300
@@ -28,7 +28,7 @@
 
 const TInt KE32MajorVersionNumber=2;
 const TInt KE32MinorVersionNumber=0;
-const TInt KE32BuildVersionNumber=2109;
+const TInt KE32BuildVersionNumber=2111;
 
 const TInt KMachineConfigurationMajorVersionNumber=1;
 const TInt KMachineConfigurationMinorVersionNumber=0;
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mmu.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmu.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -890,20 +890,31 @@
 		SPageInfo* pi = SPageInfo::FromPhysAddr(pagePhys);
 		PageFreed(pi);
 
-		// If this is an old page of a page being moved that was previously pinned
-		// then make sure it is freed as discardable otherwise despite DPager::DonatePages()
-		// having marked it as discardable it would be freed as movable.
-		__NK_ASSERT_DEBUG(pi->PagedState() != SPageInfo::EPagedPinnedMoved || aCount == 1);
-		if (pi->PagedState() == SPageInfo::EPagedPinnedMoved)
-			aZonePageType = EPageDiscard;
-
-		if(ThePager.PageFreed(pi)==KErrNone)
-			--aCount; // pager has dealt with this page, so one less for us
-		else
+		switch (ThePager.PageFreed(pi))
 			{
-			// All paged pages should have been dealt with by the pager above.
-			__NK_ASSERT_DEBUG(pi->PagedState() == SPageInfo::EUnpaged);
-			*pagesOut++ = pagePhys; // store page address for freeing later
+			case KErrNone: 
+				--aCount; // pager has dealt with this page, so one less for us
+				break;
+			case KErrCompletion:
+				// This was a pager controlled page but it is no longer required.
+				__NK_ASSERT_DEBUG(aZonePageType == EPageMovable || aZonePageType == EPageDiscard);
+				__NK_ASSERT_DEBUG(pi->PagedState() == SPageInfo::EUnpaged);
+				if (aZonePageType == EPageMovable)
+					{// This page was donated to the pager so have to free it here
+					// as aZonePageType is incorrect for this page but aPages may 
+					// contain a mixture of movable and discardable pages.
+					MmuLock::Unlock();
+					iRamPageAllocator->FreeRamPages(&pagePhys, 1, EPageDiscard);
+					aCount--; // We've freed this page here so one less to free later
+					flash = 0;	// reset flash count as we released the mmulock.
+					MmuLock::Lock();
+					break;
+					}
+				// fall through..
+			default:
+				// Free this page..
+				__NK_ASSERT_DEBUG(pi->PagedState() == SPageInfo::EUnpaged);
+				*pagesOut++ = pagePhys; // store page address for freeing later
 			}
 		}
 	MmuLock::Unlock();
@@ -922,21 +933,23 @@
 		__KTRACE_OPT(KMMU,Kern::Printf("Mmu::AllocContiguousRam returns simulated OOM %d",KErrNoMemory));
 		return KErrNoMemory;
 		}
-	// Only the page sets EAllocNoPagerReclaim and it shouldn't allocate contiguous ram.
+	// Only the pager sets EAllocNoPagerReclaim and it shouldn't allocate contiguous ram.
 	__NK_ASSERT_DEBUG(!(aFlags&EAllocNoPagerReclaim));
 #endif
 	TInt r = iRamPageAllocator->AllocContiguousRam(aCount, aPhysAddr, EPageFixed, aAlign+KPageShift);
 	if(r==KErrNoMemory && aCount > KMaxFreeableContiguousPages)
 		{
 		// flush paging cache and retry...
+		RamAllocLock::Unlock();
 		ThePager.FlushAll();
+		RamAllocLock::Lock();
 		r = iRamPageAllocator->AllocContiguousRam(aCount, aPhysAddr, EPageFixed, aAlign+KPageShift);
 		}
 	if(r!=KErrNone)
 		iRamAllocFailed = ETrue;
 	else
 		PagesAllocated((TPhysAddr*)(aPhysAddr|1), aCount, aFlags);
-	__KTRACE_OPT(KMMU,Kern::Printf("AllocContiguouseRam returns %d and aPhysAddr=0x%08x",r,aPhysAddr));
+	__KTRACE_OPT(KMMU,Kern::Printf("AllocContiguousRam returns %d and aPhysAddr=0x%08x",r,aPhysAddr));
 	return r;
 	}
 
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -336,6 +336,7 @@
 
 TInt DPager::PageFreed(SPageInfo* aPageInfo)
 	{
+	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
 	__NK_ASSERT_DEBUG(CheckLists());
 
@@ -382,7 +383,7 @@
 		// This page was pinned when it was moved but it has not been returned 
 		// to the free pool yet so make sure it is...
 		aPageInfo->SetPagedState(SPageInfo::EUnpaged);	// Must be unpaged before returned to free pool.
-		return KErrNotFound;
+		return KErrCompletion;
 
 	default:
 		__NK_ASSERT_DEBUG(0);
@@ -393,6 +394,14 @@
 	if (aPageInfo->IsDirty())
 		SetClean(*aPageInfo);
 
+	if (iNumberOfFreePages > 0)
+		{// The paging cache is not at the minimum size so safe to let the 
+		// ram allocator free this page.
+		iNumberOfFreePages--;
+		aPageInfo->SetPagedState(SPageInfo::EUnpaged);
+		return KErrCompletion;
+		}
+	// Need to hold onto this page as have reached the page cache limit.
 	// add as oldest page...
 #ifdef _USE_OLDEST_LISTS
 	aPageInfo->SetPagedState(SPageInfo::EPagedOldestClean);
@@ -449,8 +458,8 @@
 #ifdef _DEBUG
 		if (!IsPageTableUnpagedRemoveAllowed(aPageInfo))
 			__NK_ASSERT_DEBUG(0);
+#endif
 		break;
-#endif
 	default:
 		__NK_ASSERT_DEBUG(0);
 		return;
@@ -787,6 +796,9 @@
 	__NK_ASSERT_DEBUG(iNumberOfFreePages>0);
 	--iNumberOfFreePages;
 
+	// The page must be unpaged, otherwise it wasn't successfully removed 
+	// from the live list.
+	__NK_ASSERT_DEBUG(aPageInfo.PagedState() == SPageInfo::EUnpaged);
 	MmuLock::Unlock();
 
 	TPhysAddr pagePhys = aPageInfo.PhysAddr();
@@ -1861,7 +1873,12 @@
 					}
 				++pi;
 				if(((TUint)pi&(0xf<<KPageInfoShift))==0)
-					MmuLock::Flash(); // every 16 page infos
+					{
+					MmuLock::Unlock(); // every 16 page infos
+					RamAllocLock::Unlock();
+					RamAllocLock::Lock();
+					MmuLock::Lock();
+					}
 				}
 			while(pi<piEnd);
 			}
--- a/kernel/eka/release.txt	Wed Apr 14 17:22:59 2010 +0300
+++ b/kernel/eka/release.txt	Tue Apr 27 18:02:57 2010 +0300
@@ -1,3 +1,25 @@
+Version 2.00.2111
+=================
+(Made by vfebvre 09/04/2010)
+
+1.	vfebvre
+	1.	PDEF145226 Change distribution policy ID of hcr/documents to 1
+
+
+Version 2.00.2110
+=================
+(Made by vfebvre 08/04/2010)
+
+1.	shenzhou
+	1.	ou1cimx1#335076 change_otg_descriptor_returned_location
+
+2.	marisood
+	1.	DEF144852 E32TEST T_PRMACCTSTSIM fails on NE1_TB.ARMV5.UDEB.DATAPAGE
+
+3.	martai
+	1.	DEF145234 SALM-83WJYV: WDP: Potential system impact of flushing the entire page cache is
+
+
 Version 2.00.2109
 =================
 (Made by vfebvre 29/03/2010)
Binary file kernelhwsrv_info/doc_pub/base_how_to_64bit_file_server_client_porting_guide.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_64bit_file_server_file_system_plugin_porting_guide.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_align_partitions_to_media_block_boundaries_for_optimised_performance.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_armv7_cache_and_access_remapping_-_design.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_btrace.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_configure_platform_security_settings.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_crash_logging.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_debug_nonxip_problems.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_estart.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_file_caching.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_handle_sharing.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_impacts_of_demand_paging_on_kernel-side_code.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_ipc.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_message_queues.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_migrate_device_drivers_to_paging_environment.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_migrate_media_drivers_to_support_demand_paging.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_migrate_to_client-server_v2_apis.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_mmc_direct_physical_addressing.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_mmc_double_buffering.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_persisting_a_custom_restart_reason.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_port_emmc_controller.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_port_sdio_controller_supplement.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_publish_and_subscribe.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_share_file_handles.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_usb_client_porting_and_test.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_usb_mass_storage_app.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_usb_mass_storage_double_buffering.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_use_cfileman_test_framework.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_use_dma_for_sdio_data_transfers.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_use_t_fatcharsetconv_framework.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_how_to_vfp_support.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_migrating_device_drivers_dfc_q.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_migrating_kernel api preconditions checking.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_migrating_media_drivers_dma.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_smp_driver_migration_guide.doc has changed
Binary file kernelhwsrv_info/doc_pub/base_smp_user_side_migration_guide.doc has changed
--- a/kerneltest/e32test/mmu/t_cachechunk.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/kerneltest/e32test/mmu/t_cachechunk.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -98,7 +98,7 @@
 TInt PageSize;
 TInt NoFreeRam;
 RTimer Timer;
-
+TBool gFmm;
 
 
 void FillPage(TUint aOffset)
@@ -308,18 +308,44 @@
 	test_KErrNone(r);
 
 	test.Next(_L("Check Decommit on unlocked pages"));
+	// Get orignal page cache size
+	TUint minCache = 0;
+	TUint maxCache = 0;
+	TUint oldCache = 0;
+	TUint newCache = 0;
+	if (gFmm)
+		{
+		r = DPTest::CacheSize(minCache, maxCache, oldCache);
+		test_KErrNone(r);
+		}
 	r = TestChunk.Unlock(aOffset,PageSize*4);
 	test_KErrNone(r);
+
+	TUint spareCache = maxCache - oldCache;
+	if (gFmm && spareCache)
+		{// Cache wasn't at maximum so should have grown when unlocked pages were added.
+		r = DPTest::CacheSize(minCache, maxCache, newCache);
+		test_KErrNone(r);
+		TUint extraCache = (spareCache > (TUint)PageSize*4)? PageSize*4 : spareCache;
+		test_Equal(oldCache + extraCache, newCache);
+		}
 	test(FreeRam() >= NoFreeRam+PageSize*4);
 	r=TestChunk.Decommit(aOffset, PageSize*4);
 	test_KErrNone(r);
 	freeRam = FreeRam();
 	test_Compare(freeRam, >=, NoFreeRam+PageSize*4);
 	test_Equal(origChunkSize - PageSize*4, TestChunk.Size());
+
+	if (gFmm)
+		{// Cache should have shrunk after pages were decommited.
+		r = DPTest::CacheSize(minCache, maxCache, newCache);
+		test_KErrNone(r);
+		test_Equal(oldCache, newCache);
+		}
 	// Restore chunk back to original state
 	r = TestChunk.Commit(aOffset, PageSize*4);
 	test_KErrNone(r);
-	test(FreeRam() == NoFreeRam);
+	test_Equal(NoFreeRam, FreeRam());
 
 	test.Next(_L("Check Decommit on unlocked and reclaimed pages"));
 	r = TestChunk.Unlock(aOffset,PageSize*4);
@@ -351,6 +377,44 @@
 	test(freeRam==NoFreeRam);
 	test_Equal(origChunkSize, TestChunk.Size());
 
+	test.Next(_L("Check Decommit on a mixture of locked and unlocked pages"));
+	// Get orignal page cache size
+	if (gFmm)
+		{
+		r = DPTest::CacheSize(minCache, maxCache, oldCache);
+		test_KErrNone(r);
+		}
+	r = TestChunk.Unlock(aOffset,PageSize);
+	test_KErrNone(r);
+	r = TestChunk.Unlock(aOffset + PageSize*2, PageSize);
+	test_KErrNone(r);
+
+	spareCache = maxCache - oldCache;
+	if (gFmm && spareCache)
+		{// Cache wasn't at maximum so should have grown when unlocked pages were added.
+		r = DPTest::CacheSize(minCache, maxCache, newCache);
+		test_KErrNone(r);
+		TUint extraCache = (spareCache > (TUint)PageSize*2)? PageSize*2 : spareCache;
+		test_Equal(oldCache + extraCache, newCache);
+		}
+	test(FreeRam() >= NoFreeRam+PageSize*2);
+	r=TestChunk.Decommit(aOffset, PageSize*4);
+	test_KErrNone(r);
+	freeRam = FreeRam();
+	test_Compare(freeRam, >=, NoFreeRam+PageSize*4);
+	test_Equal(origChunkSize - PageSize*4, TestChunk.Size());
+
+	if (gFmm)
+		{// Cache should have shrunk after pages were decommited.
+		r = DPTest::CacheSize(minCache, maxCache, newCache);
+		test_KErrNone(r);
+		test_Equal(oldCache, newCache);
+		}
+	// Restore chunk back to original state
+	r = TestChunk.Commit(aOffset, PageSize*4);
+	test_KErrNone(r);
+	test_Equal(NoFreeRam, FreeRam());
+
 	test.End();
 	}
 
@@ -450,6 +514,10 @@
 		test.Printf(_L("This test requires an MMU\n"));
 		return KErrNone;
 		}
+	// See if were running on the Flexible Memory Model or newer.
+  	TUint32 memModelAttrib = (TUint32)UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);	
+	gFmm = (memModelAttrib & EMemModelTypeMask) >= EMemModelTypeFlexible;
+
 	test.Start(_L("Initialise test"));
 	test.Next(_L("Load gobbler LDD"));
 	TInt r = User::LoadLogicalDevice(KGobblerLddFileName);
--- a/kerneltest/e32test/resourceman/acctst/d_prmacctst.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/kerneltest/e32test/resourceman/acctst/d_prmacctst.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-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"
@@ -151,11 +151,12 @@
 	TDynamicDfcQue* dfcQ;
 	TInt r = Kern::DynamicDfcQCreate(dfcQ, KTestDfcQuePrority, KTestDfcQueBaseName);
 	TEST_KERRNONE(r);
-	iDfcQ = dfcQ;
 	if (r != KErrNone)
 		{
 		return r;
 		}
+	dfcQ->SetRealtimeState(ERealtimeStateOff);
+	iDfcQ = dfcQ;
 	SetDfcQ(iDfcQ);
 	iMsgQ.Receive();
 	return KErrNone;
--- a/kerneltest/f32test/demandpaging/t_nandpaging.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/kerneltest/f32test/demandpaging/t_nandpaging.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -275,7 +275,6 @@
 					Drive.ControlIO(KNandGetDeferStats,statsBuf,0);
 					test.Printf(_L("PG %d PO %d(%d%%) NG %d NO %d\n"),stats.iPageGarbage,  stats.iPageOther, (TInt) ((stats.iPageOther*100)/cCount), stats.iNormalGarbage,  stats.iNormalOther);
 
-					test(stats.iPageOther>0);
 				 	pageGarbageCount+=stats.iPageGarbage; 
 				 	pageOtherCount+=stats.iPageOther;			 	
 				 	normalGarbageCount+=stats.iNormalGarbage; 
@@ -299,6 +298,7 @@
 			{
 			test.Printf(_L("\nTotals: Avg %2d %d%% CC=%4d \n"), fullTot/fullcCount, (TInt)(totChangeCount*100)/fullcCount, totChangeCount);
 			test.Printf(_L("PG %d PO %d(%d%%) NG %d NO %d\n"),pageGarbageCount,  pageOtherCount,(TInt) (pageOtherCount*100/fullcCount), normalGarbageCount,  normalOtherCount );
+			test(pageOtherCount > 0);	// Ensure at least one paging conflict occurred during the test.
 			}
 
 		// If totChangeCount does not change, nand maybe busy waiting.
--- a/userlibandfileserver/fileserver/group/release.txt	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/group/release.txt	Tue Apr 27 18:02:57 2010 +0300
@@ -1,3 +1,11 @@
+Version 2.00.2051
+=================
+(Made by vfebvre 09/04/2010)
+
+1.	niccox
+	1.	DEF145248 Error in mass storage note when connecting SanDisk 16GB stick to phone
+
+
 Version 2.00.2050
 =================
 (Made by vfebvre 24/03/2010)
--- a/userlibandfileserver/fileserver/inc/f32ver.h	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/inc/f32ver.h	Tue Apr 27 18:02:57 2010 +0300
@@ -58,6 +58,6 @@
 
 @see TVersion
 */
-const TInt KF32BuildVersionNumber=2050;
+const TInt KF32BuildVersionNumber=2051;
 //
 #endif
--- a/userlibandfileserver/fileserver/shostmassstorage/client/debug.h	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/client/debug.h	Tue Apr 27 18:02:57 2010 +0300
@@ -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"
@@ -25,7 +25,8 @@
 #include <e32debug.h>
 #endif
 
-// #define _USBMS_DEBUG_PRINT_
+// #define _USBMS_DEBUG_PRINT_ 
+// #define _MSDEVICE_DEBUG_PRINT_
 
 #if defined(_USBMS_DEBUG_PRINT_) && (defined(_DEBUG) || defined(_DEBUG_RELEASE))
 /** Trace - format string  */
@@ -75,4 +76,15 @@
 #define __FNLOG(name)
 #endif
 
+
+#if defined (_MSDEVICE_DEBUG_PRINT_) && (defined(_DEBUG) || defined(_DEBUG_RELEASE))
+#define __MSDEVPRINT(t) {RDebug::Print(t);}
+#define __MSDEVPRINT1(t,a) {RDebug::Print(t,a);}
+#define __MSDEVPRINT2(t,a,b) {RDebug::Print(t,a,b);}
+#else
+#define __MSDEVPRINT(t)
+#define __MSDEVPRINT1(t,a)
+#define __MSDEVPRINT2(t,a,b)
+#endif // _MSDEVICE_DEBUG_PRINT_
+
 #endif // DEBUG_H
--- a/userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -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"
@@ -204,6 +204,7 @@
 EXPORT_C TInt RUsbHostMsDevice::MountLun(TUint32 aLunId, TInt aDriveNum)
 	{
 	__FNLOG("RUsbHostMsDevice::MountLun");
+    __MSDEVPRINT2(_L(">>> RUsbHostMsDevice::MountLun Drv=%d LUN=%d"), aDriveNum, aLunId);
 	RFs TheFs;
 	TInt r = TheFs.Connect();
 	if(r == KErrNone)
@@ -212,11 +213,12 @@
 		unitPkg().iLunID = aLunId;
 
 		r = TheFs.MountProxyDrive(aDriveNum, _L("usbhostms"), &unitPkg, *this);
+        __MSDEVPRINT1(_L("MountProxyDrive %d"), r);
 		if(r >= KErrNone)
 			{
 			r = TheFs.MountFileSystem(KFileSystem, aDriveNum);
-
-			if(r != KErrNone && r != KErrNotReady && r != KErrCorrupt)
+            __MSDEVPRINT1(_L("MountFileSystem %d"), r);
+			if(r != KErrNone && r != KErrNotReady && r != KErrCorrupt && r != KErrNotSupported)
 				{
 				TheFs.DismountFileSystem(KFileSystem, aDriveNum);
 				TheFs.DismountProxyDrive(aDriveNum);
@@ -230,6 +232,7 @@
 EXPORT_C TInt RUsbHostMsDevice::DismountLun(TInt aDriveNum)
 	{
 	__FNLOG("RUsbHostMsDevice::DismountLun");
+    __MSDEVPRINT1(_L(">>> RUsbHostMsDevice::DismountLun Drv=%d"), aDriveNum);
 	RFs TheFs;
 	TInt r;
 	r = TheFs.Connect();
--- a/userlibandfileserver/fileserver/shostmassstorage/msproxy/hostusbmsproxy.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/msproxy/hostusbmsproxy.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -154,7 +154,7 @@
 	TCapsInfo capsInfo;
 	TInt err = iUsbHostMsLun.Caps(capsInfo);
 
-    if (err == KErrNone)
+    if (err == KErrNone && capsInfo.iMediaType == EMediaHardDisk)
         {
         err = InitialiseOffset(capsInfo);
         }
@@ -538,13 +538,12 @@
 TInt CUsbHostMsProxyDrive::Caps(TDes8& anInfo)
 	{
 	__MSFNSLOG
-    __HOSTPRINT(_L("\n>>> HOST Caps"));
+    __HOSTPRINT(_L(">>> HOST Caps"));
 	TLocalDriveCapsV6Buf caps;
     caps.FillZ();
 
     TLocalDriveCapsV6& c = caps();
 
-	c.iType = EMediaHardDisk;
     c.iConnectionBusType = EConnectionBusUsb;
 	c.iDriveAtt = KDriveAttLocal | KDriveAttRemovable | KDriveAttExternal;
 	c.iMediaAtt = KMediaAttFormattable;
@@ -552,32 +551,50 @@
 
 	TCapsInfo capsInfo;
 	TInt r = iUsbHostMsLun.Caps(capsInfo);
+
 	if (KErrNone == r)
 		{
-        c.iBlockSize = capsInfo.iBlockLength;
-        TUint64 size = iMsDataMemMap.DataSize();
-        if (size == 0)
-            {
-            // No valid partitions so specify the size of the disk
-            size = static_cast<TUint64>(capsInfo.iNumberOfBlocks) * capsInfo.iBlockLength;
-            }
-        c.iSize = size;
-
-        c.iEraseBlockSize = 0;
+        c.iType = capsInfo.iMediaType;
 
-        if (capsInfo.iWriteProtect)
+        if (capsInfo.iMediaType == EMediaHardDisk)
             {
-            c.iMediaAtt |= KMediaAttWriteProtected;
+            c.iBlockSize = capsInfo.iBlockLength;
+            TUint64 size = iMsDataMemMap.DataSize();
+    
+            if (size == 0)
+                {
+                // No valid partitions so specify the size of the disk
+                size = static_cast<TUint64>(capsInfo.iNumberOfBlocks) * capsInfo.iBlockLength;
+                }
+            c.iSize = size;
+    
+            c.iEraseBlockSize = 0;
+    
+            if (capsInfo.iWriteProtect)
+                {
+                c.iMediaAtt |= KMediaAttWriteProtected;
+                }
+                
+            static const TInt K512ByteSectorSize = 0x200; // 512
+            if(K512ByteSectorSize != capsInfo.iBlockLength)
+                {
+                // not formattable if sector size is not 512
+                c.iMediaAtt &= ~KMediaAttFormattable;
+                }
+            __HOSTPRINT4(_L("<<< HOST Caps Block[num=0x%x size=0x%x] Media[size=0x%lx WP=0x%x]"),
+                        capsInfo.iNumberOfBlocks, capsInfo.iBlockLength,
+                        caps().iSize, caps().iMediaAtt);
             }
-            
-        static const TInt K512ByteSectorSize = 0x200; // 512
-        if(K512ByteSectorSize != capsInfo.iBlockLength)
-        	{
-	        c.iMediaAtt &= ~KMediaAttFormattable;
-        	}
-        __HOSTPRINT4(_L("<<< HOST Caps Block[num=0x%x size=0x%x] Media[size=0x%lx WP=0x%x]"),
-                    capsInfo.iNumberOfBlocks, capsInfo.iBlockLength,
-		            caps().iSize, caps().iMediaAtt);
+        else if (capsInfo.iMediaType == EMediaCdRom)
+            {
+            // not formattable
+            c.iMediaAtt &= ~KMediaAttFormattable;
+            __HOSTPRINT(_L(">>> HOST Caps MediaType = EMediaCdRom"));
+            }
+        else
+            {
+            // do nothing
+            }
 		}
 	else if (KErrNotReady)
         {
--- a/userlibandfileserver/fileserver/shostmassstorage/server/controller/cusbhostmsdevice.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/controller/cusbhostmsdevice.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -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"
@@ -152,8 +152,8 @@
 void CUsbHostMsDevice::InitLunL(TLun aLun)
 	{
     __MSFNLOG
-	SetLunL(aLun);
-    iLuList.GetLuL(aLun).InitL();
+	CUsbHostMsLogicalUnit& lu = SetLunL(aLun);
+    lu.InitL();
 	}
 
 
@@ -174,7 +174,7 @@
 	for (TInt i = 0; i < iLuList.Count(); i++)
 		{
 		CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(i);
-		SetLunL(lu.Lun());
+		SetLunL(lu);
 		lu.SuspendL();
 		}
 
@@ -217,21 +217,31 @@
     return iLuList.GetLuL(aLunNum);
     }
 
-void CUsbHostMsDevice::SetLunL(TLun aLun)
+
+void CUsbHostMsDevice::SetLunL(CUsbHostMsLogicalUnit& aLu)
 	{
     __MSFNLOG
-	if (aLun <= iMaxLun)
+    TLun lun = aLu.Lun();
+	if (lun <= iMaxLun)
         {
-        __HOSTPRINT1(_L("SetLun %d"), aLun);
-        iTransport->SetLun(aLun);
-        CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(aLun);
-		if (lu.IsReadyToSuspend())
+        __HOSTPRINT1(_L("SetLun %d"), lun);
+        iTransport->SetLun(lun);
+		if (aLu.IsReadyToSuspend())
 			{
-			lu.CancelReadyToSuspend();
+			aLu.CancelReadyToSuspend();
 			}
 		}
 	}
 
+
+CUsbHostMsLogicalUnit& CUsbHostMsDevice::SetLunL(TLun aLun)
+	{
+    __MSFNLOG
+    CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(aLun);
+    SetLunL(lu);
+    return lu;
+	}
+
 /**
 Starts timer to periodically check LUN. If the timer is not yet running then
 start it.
@@ -290,7 +300,7 @@
 	for (TInt i = 0; i < iLuList.Count(); i++)
 		{
 		CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(i);
-		SetLunL(lu.Lun());
+		SetLunL(lu);
 		TRAP(err, lu.DoLunReadyCheckL());
 		}
 	}
@@ -318,7 +328,7 @@
 	for (TInt i = 0; i < iLuList.Count(); i++)
 		{
 		CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(i);
-		SetLunL(lu.Lun());
+		SetLunL(lu);
 		lu.SuspendL();
 		}
 
@@ -332,7 +342,7 @@
 	for (TInt i = 0; i < iLuList.Count(); i++)
 		{
 		CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(i);
-		SetLunL(lu.Lun());
+		SetLunL(lu);
 		lu.ResumeL();
 		}
 	}
--- a/userlibandfileserver/fileserver/shostmassstorage/server/controller/cusbhostmsdevicethread.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/controller/cusbhostmsdevicethread.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -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"
@@ -419,6 +419,7 @@
 	TPtrC8 pLun((TUint8*)&iLunId, sizeof(TUint32));
 	aMessage.WriteL(3, pLun);
 	iLunId -= 1;	// We represent LunId in MSC from 0 to MaxLun-1 as represented in BOT
+    __HOSTPRINT1(_L("RegisterLogicalUnitL LUN=%d "), iLunId);
 	iUsbHostMsDevice->AddLunL(iLunId);
 	iUsbHostMsDevice->InitLunL(iLunId);
 	}
--- a/userlibandfileserver/fileserver/shostmassstorage/server/controller/include/cusbhostmsdevice.h	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/controller/include/cusbhostmsdevice.h	Tue Apr 27 18:02:57 2010 +0300
@@ -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"
@@ -41,7 +41,8 @@
 	TLun GetAndSetLunL(const RMessage2& aMessage);
     CUsbHostMsLogicalUnit& GetLuL(TInt aLunNum) const;
 
-	void SetLunL(TLun aLun);
+    void SetLunL(CUsbHostMsLogicalUnit& aLu);
+	CUsbHostMsLogicalUnit& SetLunL(TLun aLun);
 	void SetMaxLun(TLun aMaxLun);
 	TLun GetMaxLun() const;
 
--- a/userlibandfileserver/fileserver/shostmassstorage/server/controller/tlogicalunitlist.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/controller/tlogicalunitlist.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -102,7 +102,7 @@
     TInt index;
     for (index = 0; index < iLu.Count(); index++)
         {
-        __HOSTPRINT2(_L("search %d : interface id = %d\n"), aLun, iLu[index]->Lun());
+        __HOSTPRINT2(_L("search LUN=%d : interface id = %d"), aLun, iLu[index]->Lun());
         if (iLu[index]->Lun() == aLun)
             {
             break;
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cmassstoragefsm.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cmassstoragefsm.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -321,6 +321,7 @@
 TInt CMassStorageFsm::ConnectLogicalUnitL()
     {
 	__MSFNLOG
+    __HOSTPRINT(_L("CMassStorageFsm::ConnectLogicalUnitL()"));        
     TInt err = KErrNone;
     for (;;)
          {
@@ -340,6 +341,7 @@
 TInt CMassStorageFsm::DisconnectLogicalUnitL()
     {
 	__MSFNLOG
+    __HOSTPRINT(_L("CMassStorageFsm::DisconnectLogicalUnitL()"));
     TInt err = KErrNone;
     for (;;)
          {
@@ -370,6 +372,7 @@
     TRAPD(err,  event = EntryL());
     if (err == KErrNotSupported)
         {
+        __HOSTPRINT(_L("FSM ProcessState returning with KErrNotSupported"));
         return KErrNotSupported;
         }
     User::LeaveIfError(err);
@@ -557,7 +560,11 @@
             aFsm.SetState(TMassStorageState::EReadCapacityState);
         }
     else
-        aFsm.SetState(TMassStorageState::EInquiryState);
+        {
+        __HOSTPRINT(_L("SBC is not set !!"));
+        aFsm.SetState(TMassStorageState::EReadCapacityState);
+        }
+        
     return KErrNone;
     }
 
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -104,7 +104,11 @@
     do
         {
         retryCounter--;
-        iFsm->ConnectLogicalUnitL();
+        TInt err = iFsm->ConnectLogicalUnitL();
+        if (err == KErrNotSupported)
+            {
+            break;
+            }
         if (iFsm->IsConnected())
             {
             iState = EConnected;
@@ -133,6 +137,10 @@
                           TInt aLength)
     {
 	__MSFNLOG
+
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     if(!IsConnected())
 		User::Leave(KErrNotReady);
     iSbcInterface->iBlockTransfer.ReadL(*this, aPos, aLength, aBuf);
@@ -142,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));
 
@@ -196,6 +207,9 @@
                            TInt aLength)
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     if(!IsConnected())
 		User::Leave(KErrNotReady);
     iSbcInterface->iBlockTransfer.WriteL(*this, aPosition, aLength, aBuf);
@@ -205,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();
@@ -250,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;
 
@@ -351,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;
     }
 
 
@@ -400,6 +443,11 @@
 TInt CScsiProtocol::MsReadCapacityL()
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        {
+        User::Leave(KErrNotSupported);
+        }
+
     // READ CAPACITY
     TUint32 blockSize;
     TUint32 lastLba;
@@ -420,6 +468,9 @@
 TInt CScsiProtocol::MsModeSense10L()
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     TBool writeProtected;
     TInt err = iSbcInterface->ModeSense10L(TSbcClientInterface::EReturnAllModePages, writeProtected);
 
@@ -441,6 +492,9 @@
 TInt CScsiProtocol::MsModeSense6L()
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     TBool writeProtected;
     TInt err = iSbcInterface->ModeSense6L(TSbcClientInterface::EReturnAllModePages, writeProtected);
 
@@ -462,6 +516,9 @@
 TInt CScsiProtocol::MsStartStopUnitL(TBool aStart)
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     return iSbcInterface->StartStopUnitL(aStart);
     }
 
@@ -492,12 +549,15 @@
         iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady &&
         iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired)
         {
-        // start unit
-        err = iSbcInterface->StartStopUnitL(ETrue);
-        if (err)
-            {
-            User::LeaveIfError(MsRequestSenseL());
-            }
+		if (iSbcInterface)
+			{
+	        // start unit
+			err = iSbcInterface->StartStopUnitL(ETrue);
+	        if (err)
+		        {
+			    User::LeaveIfError(MsRequestSenseL());
+				}			
+			}
         }
 
     err = GetSystemWideSenseError(iSenseInfo);
@@ -745,7 +805,7 @@
     __MSFNLOG
 	TInt err = KErrNone;
 
-	if(iFsm->IsRemovableMedia() || iState != EConnected)
+	if(iRemovableMedia || iState != EConnected)
         {
 		iFsm->SetStatusCheck();
 		TRAP(err, iFsm->ConnectLogicalUnitL());
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiprimarycmds.cpp	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiprimarycmds.cpp	Tue Apr 27 18:02:57 2010 +0300
@@ -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"
@@ -84,7 +84,6 @@
 void TScsiClientInquiryResp::DecodeInquiry(const TDesC8& aPtr)
     {
 	__MSFNSLOG
-    __SCSIPRINT(_L("--> SCSI INQUIRY"));
     iPeripheralInfo.iRemovable = (aPtr[1] & 0x80) ? ETrue : EFalse;
 
     iPeripheralInfo.iPeripheralQualifier = aPtr[0] >> 5;
--- a/userlibandfileserver/fileserver/shostmassstorage/shared/shared.h	Wed Apr 14 17:22:59 2010 +0300
+++ b/userlibandfileserver/fileserver/shostmassstorage/shared/shared.h	Tue Apr 27 18:02:57 2010 +0300
@@ -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"
@@ -77,6 +77,8 @@
     TUint32 iBlockLength;
     /** Media write protect */
     TBool iWriteProtect;
+    /** Block device or CD-ROM */
+    TMediaType iMediaType;
     };