branch | RCL_3 |
changeset 294 | 039a3e647356 |
parent 268 | 345b1ca54e88 |
268:345b1ca54e88 | 294:039a3e647356 |
---|---|
27 #pragma warning(disable: 4127) // disabling warning "conditional expression is constant" |
27 #pragma warning(disable: 4127) // disabling warning "conditional expression is constant" |
28 #endif |
28 #endif |
29 #include "locmediaTraces.h" |
29 #include "locmediaTraces.h" |
30 #endif |
30 #endif |
31 |
31 |
32 |
|
32 #if defined(_DEBUG) && defined(__DEMAND_PAGING__) |
33 #if defined(_DEBUG) && defined(__DEMAND_PAGING__) |
33 //#define __DEBUG_DEMAND_PAGING__ |
34 //#define __DEBUG_DEMAND_PAGING__ |
34 #endif |
35 #endif |
35 |
36 |
36 |
37 |
68 TPasswordStore* ThePasswordStore=NULL; |
69 TPasswordStore* ThePasswordStore=NULL; |
69 |
70 |
70 class DPrimaryMediaBase::DBody : public DBase |
71 class DPrimaryMediaBase::DBody : public DBase |
71 { |
72 { |
72 public: |
73 public: |
73 DBody(DPrimaryMediaBase& aPrimaryMediaBase); |
|
74 public: |
|
75 DPrimaryMediaBase& iPrimaryMediaBase; // ptr to parent |
|
76 TInt iPhysDevIndex; |
74 TInt iPhysDevIndex; |
77 TInt iRequestCount; |
75 TInt iRequestCount; |
78 #ifdef __DEMAND_PAGING__ |
76 #ifdef __DEMAND_PAGING__ |
79 DMediaPagingDevice* iPagingDevice; |
77 DMediaPagingDevice* iPagingDevice; |
80 TInt iPageSizeMsk; // Mask of page size (e.g. 4096-1 -> 4095) |
78 TInt iPageSizeMsk; // Mask of page size (e.g. 4096-1 -> 4095) |
81 TInt iPageSizeLog2; // LOG2 of page size (i.e. 4096 -> 12) |
79 TInt iPageSizeLog2; // LOG2 of page size (i.e. 4096 -> 12) |
82 TInt iMediaChanges; |
80 TInt iMediaChanges; |
83 #endif |
81 #endif |
84 |
|
85 // This bit mask indicates which local drives the media is attached to |
|
86 TUint32 iRegisteredDriveMask; |
|
87 |
|
88 // Set to ETrue for media extension drivers |
|
89 TBool iMediaExtension; |
|
90 |
|
91 // Media change DFCs to allow media change events from attached media |
|
92 // to be handled in the context of an extension media's thread |
|
93 TDfc iMediaChangeDfc; |
|
94 TDfc iMediaPresentDfc; |
|
95 }; |
82 }; |
96 |
83 |
97 #ifdef __DEMAND_PAGING__ |
84 #ifdef __DEMAND_PAGING__ |
98 DMediaPagingDevice* ThePagingDevices[KMaxLocalDrives]; |
85 DMediaPagingDevice* ThePagingDevices[KMaxLocalDrives]; |
99 DPrimaryMediaBase* TheRomPagingMedia = NULL; |
86 DPrimaryMediaBase* TheRomPagingMedia = NULL; |
100 DPrimaryMediaBase* TheDataPagingMedia = NULL; |
87 DPrimaryMediaBase* TheDataPagingMedia = NULL; |
101 TLocDrv* TheDataPagingDrive = NULL; |
|
102 TBool DataPagingDeviceRegistered = EFalse; |
88 TBool DataPagingDeviceRegistered = EFalse; |
103 class DPinObjectAllocator; |
89 class DPinObjectAllocator; |
104 DPinObjectAllocator* ThePinObjectAllocator = NULL; |
90 DPinObjectAllocator* ThePinObjectAllocator = NULL; |
105 |
91 |
106 // The paging media might share a DfcQ with other non-paging media (e.g. 2 MMC/SD cards sharing the same stack) |
92 // The paging media might share a DfcQ with other non-paging media (e.g. 2 MMC/SD cards sharing the same stack) |
107 // In this case, we need to avoid taking page faults on the non-paging media too, hence the need for these checks: |
93 // In this case, we need to avoid taking page faults on the non-paging media too, hence the need for these checks: |
108 inline TBool DataPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
94 inline TBool DataPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
109 {return TheDataPagingMedia && TheDataPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;} |
95 {return TheDataPagingMedia && TheDataPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;} |
110 |
|
111 |
|
112 TBool DataPagingMedia(DPrimaryMediaBase* aPrimaryMedia) |
|
113 { |
|
114 for (TLocDrv* drv = TheDataPagingDrive; drv; drv = drv->iNextDrive) |
|
115 if (drv->iPrimaryMedia == aPrimaryMedia) |
|
116 return ETrue; |
|
117 return EFalse; |
|
118 } |
|
119 |
|
120 inline TBool RomPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
96 inline TBool RomPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
121 {return TheRomPagingMedia && TheRomPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;} |
97 {return TheRomPagingMedia && TheRomPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;} |
122 |
|
123 |
|
124 #if defined(_DEBUG) |
|
125 #define SETDEBUGFLAG(aBitNum) {Kern::SuperPage().iDebugMask[aBitNum >> 5] |= (1 << (aBitNum & 31));} |
|
126 #define CLRDEBUGFLAG(aBitNum) {Kern::SuperPage().iDebugMask[aBitNum >> 5] &= ~(1 << (aBitNum & 31));} |
|
127 #else |
|
128 #define SETDEBUGFLAG(aBitNum) |
|
129 #define CLRDEBUGFLAG(aBitNum) |
|
130 #endif |
|
131 |
98 |
132 |
99 |
133 |
100 |
134 /* |
101 /* |
135 DPinObjectAllocator |
102 DPinObjectAllocator |
136 |
103 |
137 Internal class which contains : |
104 Internal class which contains : |
138 (1) a queue of pre-allocated TVirtualPinObject's; |
105 (1) a queue of pre-allocated TVirtualPinObject's; |
139 (2) a single pre-allocated DFragmentationPagingLock object: |
106 (2) a single pre-allocated DFragmentationPagingLock object: |
140 this may be used if there are no TVirtualPinObject's available or if Kern::PinVirtualMemory() fails |
107 this may be used if there are no TVirtualPinObject's available or if Kern::PinVirtualMemory() fails |
141 @internalTechnology |
|
142 */ |
108 */ |
143 NONSHARABLE_CLASS(DPinObjectAllocator) : public DBase |
109 NONSHARABLE_CLASS(DPinObjectAllocator) : public DBase |
144 { |
110 { |
145 public: |
111 public: |
146 /* |
112 /* |
190 { |
156 { |
191 iPreAllocatedDataLock->Cleanup(); |
157 iPreAllocatedDataLock->Cleanup(); |
192 delete iPreAllocatedDataLock; |
158 delete iPreAllocatedDataLock; |
193 } |
159 } |
194 |
160 |
195 for (TInt n=0; iVirtualPinContainers!= NULL && n<iObjectCount; n++) |
161 for (TInt n=0; n<iObjectCount; n++) |
196 { |
162 { |
197 SVirtualPinContainer& virtualPinContainer = iVirtualPinContainers[n]; |
163 SVirtualPinContainer& virtualPinContainer = iVirtualPinContainers[n]; |
198 if (virtualPinContainer.iObject) |
164 if (virtualPinContainer.iObject) |
199 Kern::DestroyVirtualPinObject(virtualPinContainer.iObject); |
165 Kern::DestroyVirtualPinObject(virtualPinContainer.iObject); |
200 } |
166 } |
225 OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT2, this, r ); |
191 OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT2, this, r ); |
226 return r; |
192 return r; |
227 } |
193 } |
228 |
194 |
229 |
195 |
230 iVirtualPinContainers = new SVirtualPinContainer[aObjectCount]; |
196 SVirtualPinContainer* iVirtualPinContainers = new SVirtualPinContainer[aObjectCount]; |
231 if (iVirtualPinContainers == NULL) |
197 if (iVirtualPinContainers == NULL) |
232 { |
198 { |
233 OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT3, this, KErrNoMemory ); |
199 OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT3, this, KErrNoMemory ); |
234 return KErrNoMemory; |
200 return KErrNoMemory; |
235 } |
201 } |
292 OstTraceFunctionExit1( DPINOBJECTALLOCATOR_RELEASEPINOBJECT_EXIT, this ); |
258 OstTraceFunctionExit1( DPINOBJECTALLOCATOR_RELEASEPINOBJECT_EXIT, this ); |
293 } |
259 } |
294 |
260 |
295 #endif // __DEMAND_PAGING__ |
261 #endif // __DEMAND_PAGING__ |
296 |
262 |
297 |
|
298 /* |
|
299 TDriveIterator |
|
300 |
|
301 Internal class which supports iterating through all local drives (TLocDrv's) |
|
302 If there are media extensions present, then this will iterate through all attached drives. |
|
303 @internalTechnology |
|
304 */ |
|
305 class TDriveIterator |
|
306 { |
|
307 public: |
|
308 TDriveIterator(); |
|
309 TLocDrv* NextDrive(); |
|
310 inline TInt Index() |
|
311 {return iIndex;} |
|
312 static TLocDrv* GetDrive(TInt aDriveNum, DPrimaryMediaBase* aPrimaryMedia); |
|
313 static TLocDrv* GetPhysicalDrive(TLocDrv* aDrv); |
|
314 |
|
315 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__) |
|
316 static DMediaPagingDevice* PagingDevice(TInt aDriveNum, DPagingDevice::TType aType); |
|
317 #endif |
|
318 |
|
319 private: |
|
320 TInt iIndex; |
|
321 TLocDrv* iDrive; |
|
322 }; |
|
323 |
|
324 TDriveIterator::TDriveIterator() : |
|
325 iIndex(0), iDrive(NULL) |
|
326 { |
|
327 } |
|
328 |
|
329 TLocDrv* TDriveIterator::NextDrive() |
|
330 { |
|
331 if (iDrive) // i.e. if not first time |
|
332 { |
|
333 if (iDrive->iNextDrive) |
|
334 { |
|
335 iDrive = iDrive->iNextDrive; |
|
336 return iDrive; |
|
337 } |
|
338 iIndex++; |
|
339 } |
|
340 |
|
341 for (iDrive = NULL; iIndex < KMaxLocalDrives; iIndex++) |
|
342 { |
|
343 iDrive = TheDrives[iIndex]; |
|
344 if (iDrive) |
|
345 break; |
|
346 } |
|
347 |
|
348 return iDrive; |
|
349 } |
|
350 |
|
351 /* |
|
352 Returns the first TLocDrv in the chain of attached drives which matches DPrimaryMediaBase |
|
353 */ |
|
354 TLocDrv* TDriveIterator::GetDrive(TInt aDriveNum, DPrimaryMediaBase* aPrimaryMedia) |
|
355 { |
|
356 TLocDrv* drive = TheDrives[aDriveNum]; |
|
357 while (drive && drive->iPrimaryMedia != aPrimaryMedia) |
|
358 { |
|
359 drive = drive->iNextDrive ? drive->iNextDrive : NULL; |
|
360 } |
|
361 return drive; |
|
362 } |
|
363 |
|
364 /* |
|
365 Returns the last TLocDrv in the chain of attached drives - |
|
366 i.e. the TLocDrv attached to physical media rather than a TLocDrv corresponding to a media extension |
|
367 */ |
|
368 TLocDrv* TDriveIterator::GetPhysicalDrive(TLocDrv* aDrv) |
|
369 { |
|
370 __ASSERT_DEBUG(aDrv, LOCM_FAULT()); |
|
371 while (aDrv->iNextDrive) |
|
372 aDrv = aDrv->iNextDrive; |
|
373 return aDrv; |
|
374 } |
|
375 |
|
376 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__) |
|
377 DMediaPagingDevice* TDriveIterator::PagingDevice(TInt aDriveNum, DPagingDevice::TType aType) |
|
378 { |
|
379 TLocDrv* drive = TheDrives[aDriveNum]; |
|
380 DMediaPagingDevice* pagingDevice = drive ? drive->iPrimaryMedia->iBody->iPagingDevice : NULL; |
|
381 while (drive && (pagingDevice == NULL || (pagingDevice->iType & aType) == 0)) |
|
382 { |
|
383 drive = drive->iNextDrive ? drive->iNextDrive : NULL; |
|
384 pagingDevice = drive ? drive->iPrimaryMedia->iBody->iPagingDevice : NULL; |
|
385 } |
|
386 return pagingDevice; |
|
387 } |
|
388 #endif |
|
389 |
|
390 /******************************************** |
263 /******************************************** |
391 * Local drive device base class |
264 * Local drive device base class |
392 ********************************************/ |
265 ********************************************/ |
393 DECLARE_EXTENSION_LDD() |
266 DECLARE_EXTENSION_LDD() |
394 { |
267 { |
437 } |
310 } |
438 |
311 |
439 /******************************************** |
312 /******************************************** |
440 * Local drive interface class |
313 * Local drive interface class |
441 ********************************************/ |
314 ********************************************/ |
442 DLocalDrive::DLocalDrive() : |
315 DLocalDrive::DLocalDrive() |
443 iMediaChangeObserver(MediaChangeCallback, this, TCallBackLink::EDLocalDriveObject) |
|
444 { |
316 { |
445 // iLink.iNext=NULL; |
317 // iLink.iNext=NULL; |
446 } |
318 } |
447 |
319 |
448 DLocalDrive::~DLocalDrive() |
320 DLocalDrive::~DLocalDrive() |
619 m.Id()=ECaps; |
491 m.Id()=ECaps; |
620 m.RemoteDes()=(TAny*)capsBuf.Ptr(); // overload this |
492 m.RemoteDes()=(TAny*)capsBuf.Ptr(); // overload this |
621 m.Length()=KMaxLocalDriveCapsLength; // for pinning |
493 m.Length()=KMaxLocalDriveCapsLength; // for pinning |
622 r=iDrive->Request(m); |
494 r=iDrive->Request(m); |
623 |
495 |
496 if(r == KErrNone && iDrive->iMedia != NULL && iDrive->iMedia->iDriver != NULL) |
|
497 { |
|
498 // Fill in default media size if not specified by the driver |
|
499 // |
|
500 // - This uses the members of TLocalDriveCapsV4 which was primarily used |
|
501 // to report NAND flash characteristics, but are general enough to be |
|
502 // used to report the size of any type of media without adding yet |
|
503 // another extension to TLocalDriveCapsVx. |
|
504 // |
|
505 |
|
506 TLocalDriveCapsV4& caps = *(TLocalDriveCapsV4*)capsBuf.Ptr(); |
|
507 |
|
508 if(caps.iSectorSizeInBytes == 0) |
|
509 { |
|
510 // Fill in a default value for the disk sector size |
|
511 caps.iSectorSizeInBytes = 512; |
|
512 |
|
513 // Zero the number of sectors, as a sector count makes no sense without a sector size |
|
514 // - Fault in debug mode if a sector count is provided to ensure that media driver creators |
|
515 // set this value,but in release mode continue gracefully be recalculating the sector count. |
|
516 __ASSERT_DEBUG(caps.iNumberOfSectors == 0, LOCM_FAULT()); |
|
517 caps.iNumberOfSectors = 0; |
|
518 caps.iNumPagesPerBlock = 1; // ...to ensure compatiility with NAND semantics |
|
519 } |
|
520 |
|
521 if(caps.iNumberOfSectors == 0) |
|
522 { |
|
523 const Int64 totalSizeInSectors = iDrive->iMedia->iDriver->TotalSizeInBytes() / caps.iSectorSizeInBytes; |
|
524 __ASSERT_DEBUG(I64HIGH(totalSizeInSectors) == 0, LOCM_FAULT()); |
|
525 |
|
526 if(I64HIGH(totalSizeInSectors) == 0) |
|
527 { |
|
528 caps.iNumberOfSectors = I64LOW(totalSizeInSectors); |
|
529 } |
|
530 } |
|
531 } |
|
624 |
532 |
625 #if defined(OST_TRACE_COMPILER_IN_USE) && defined(_DEBUG) |
533 #if defined(OST_TRACE_COMPILER_IN_USE) && defined(_DEBUG) |
626 const TLocalDriveCapsV5& caps=*(const TLocalDriveCapsV5*)capsBuf.Ptr(); |
534 const TLocalDriveCapsV5& caps=*(const TLocalDriveCapsV5*)capsBuf.Ptr(); |
627 #endif |
535 #endif |
628 |
536 |
687 break; |
595 break; |
688 case RLocalDrive::EControlIsRemovable: |
596 case RLocalDrive::EControlIsRemovable: |
689 { |
597 { |
690 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLISREMOVABLE, "EControlIsRemovable; TLocDrvRequest Object=0x%x", (TUint) &m); |
598 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLISREMOVABLE, "EControlIsRemovable; TLocDrvRequest Object=0x%x", (TUint) &m); |
691 TInt sockNum; |
599 TInt sockNum; |
692 |
600 r=iDrive->iPrimaryMedia->IsRemovableDevice(sockNum); |
693 // Pass request on to last chained drive |
|
694 TLocDrv* drv = TDriveIterator::GetPhysicalDrive(iDrive); |
|
695 r = drv->iPrimaryMedia->IsRemovableDevice(sockNum); |
|
696 |
|
697 if (r) |
601 if (r) |
698 kumemput32(a1,&sockNum,sizeof(TInt)); |
602 kumemput32(a1,&sockNum,sizeof(TInt)); |
699 break; |
603 break; |
700 } |
604 } |
701 case RLocalDrive::EControlControlIO: |
605 case RLocalDrive::EControlControlIO: |
734 case RLocalDrive::EControlSetMountInfo: |
638 case RLocalDrive::EControlSetMountInfo: |
735 { |
639 { |
736 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLSETMOUNTINFO, "EControlSetMountInfo; TLocDrvRequest Object=0x%x", (TUint) &m); |
640 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLSETMOUNTINFO, "EControlSetMountInfo; TLocDrvRequest Object=0x%x", (TUint) &m); |
737 m.Id()=ERead; |
641 m.Id()=ERead; |
738 r=m.ProcessMessageData(a1); |
642 r=m.ProcessMessageData(a1); |
739 |
643 DPrimaryMediaBase* pM=iDrive->iPrimaryMedia; |
740 // Pass request on to last chained drive |
|
741 TLocDrv* drv = TDriveIterator::GetPhysicalDrive(iDrive); |
|
742 DPrimaryMediaBase* pM = drv->iPrimaryMedia; |
|
743 |
|
744 if(!pM || r!=KErrNone) |
644 if(!pM || r!=KErrNone) |
745 break; |
645 break; |
746 |
646 |
747 if (pM->iMountInfo.iThread) |
647 if (pM->iMountInfo.iThread) |
748 { |
648 { |
976 case RLocalDrive::EControlQueryDevice: |
876 case RLocalDrive::EControlQueryDevice: |
977 { |
877 { |
978 TBuf8<KMaxQueryDeviceLength> queryBuf; |
878 TBuf8<KMaxQueryDeviceLength> queryBuf; |
979 queryBuf.SetMax(); |
879 queryBuf.SetMax(); |
980 queryBuf.FillZ(); |
880 queryBuf.FillZ(); |
981 |
881 |
982 DThread* pT = m.Client(); |
|
983 r = Kern::ThreadDesRead(pT, (TDes8*)a2, queryBuf, 0 ,KChunkShiftBy0); |
|
984 |
|
985 queryBuf.SetMax(); |
|
986 m.Id() = EQueryDevice; |
882 m.Id() = EQueryDevice; |
987 m.iArg[0] = a1; // RLocalDrive::TQueryDevice |
883 m.iArg[0] = a1; // RLocalDrive::TQueryDevice |
988 m.RemoteDes() = (TAny*)queryBuf.Ptr(); // overload this |
884 m.RemoteDes() = (TAny*)queryBuf.Ptr(); // overload this |
989 m.Length() = KMaxQueryDeviceLength; |
885 m.Length() = KMaxLocalDriveCapsLength; // for pinning |
990 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE, "EQueryDevice; TLocDrvRequest Object=0x%x", (TUint) &m); |
886 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE, "EQueryDevice; TLocDrvRequest Object=0x%x", (TUint) &m); |
991 r=iDrive->Request(m); |
887 r=iDrive->Request(m); |
992 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE_RETURN, "EQueryDevice Return; TLocDrvRequest Object=0x%x", (TUint) &m); |
888 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE_RETURN, "EQueryDevice Return; TLocDrvRequest Object=0x%x", (TUint) &m); |
993 Kern::InfoCopy(*(TDes8*)a2, queryBuf); |
889 Kern::InfoCopy(*(TDes8*)a2, queryBuf); |
994 break; |
890 break; |
1139 void DLocalDrive::UnlockMountInfo(DPrimaryMediaBase& aPrimaryMedia) |
1035 void DLocalDrive::UnlockMountInfo(DPrimaryMediaBase& aPrimaryMedia) |
1140 { |
1036 { |
1141 OstTrace1(TRACE_FLOW, DLOCALDRIVE_UNLOCKMOUNTINFO_ENTRY, "> DLocalDrive::UnlockMountInfo;aPrimaryMedia=%x", (TUint) &aPrimaryMedia); |
1037 OstTrace1(TRACE_FLOW, DLOCALDRIVE_UNLOCKMOUNTINFO_ENTRY, "> DLocalDrive::UnlockMountInfo;aPrimaryMedia=%x", (TUint) &aPrimaryMedia); |
1142 |
1038 |
1143 DMediaPagingDevice* pagingDevice = aPrimaryMedia.iBody->iPagingDevice; |
1039 DMediaPagingDevice* pagingDevice = aPrimaryMedia.iBody->iPagingDevice; |
1144 if (pagingDevice == NULL) |
1040 if (pagingDevice == NULL || pagingDevice->iMountInfoDataLock == NULL) |
1145 { |
1041 { |
1146 OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT1, this ); |
1042 OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT1, this ); |
1147 return; |
1043 return; |
1148 } |
1044 } |
1149 |
1045 |
1171 |
1067 |
1172 OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT2, this ); |
1068 OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT2, this ); |
1173 } |
1069 } |
1174 #endif // __DEMAND_PAGING__ |
1070 #endif // __DEMAND_PAGING__ |
1175 |
1071 |
1176 void DLocalDrive::NotifyChange() |
1072 void DLocalDrive::NotifyChange(DPrimaryMediaBase& aPrimaryMedia, TBool aMediaChange) |
1177 { |
1073 { |
1178 OstTrace0( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange"); |
1074 OstTraceExt2( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange;aPrimaryMedia=%x;aMediaChange=%d", (TUint) &aPrimaryMedia, aMediaChange ); |
1179 |
1075 #ifndef __DEMAND_PAGING__ |
1180 |
1076 aPrimaryMedia; |
1181 // Complete any notification request on media change |
1077 #endif |
1182 DThread* pC=NULL; |
1078 |
1183 NKern::LockSystem(); |
1079 // Complete any notification request on media change or power down |
1184 if (iCleanup.iThread) |
1080 if (aMediaChange) |
1185 { |
1081 { |
1186 pC=iCleanup.iThread; |
1082 DThread* pC=NULL; |
1187 pC->Open(); |
1083 NKern::LockSystem(); |
1188 } |
1084 if (iCleanup.iThread) |
1189 NKern::UnlockSystem(); |
1085 { |
1190 if (pC) |
1086 pC=iCleanup.iThread; |
1191 { |
1087 pC->Open(); |
1192 TBool b = ETrue; |
1088 } |
1193 // if change not yet queued, queue it now |
1089 NKern::UnlockSystem(); |
1194 if (iNotifyChangeRequest->IsReady()) |
1090 if (pC) |
1195 { |
1091 { |
1196 *((TBool*) iNotifyChangeRequest->Buffer()) = b; |
1092 TBool b = ETrue; |
1197 Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone); |
1093 // if change not yet queued, queue it now |
1198 } |
1094 if (iNotifyChangeRequest->IsReady()) |
1199 // If change has not even been requested by the client, maintain the pre-wdp behaviour |
1095 { |
1200 // and write data immediately back to client (possibly taking a page fault) |
1096 *((TBool*) iNotifyChangeRequest->Buffer()) = b; |
1201 // N.B. Must NOT do this on data paging media |
1097 Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone); |
1098 } |
|
1099 // If change has not even been requested by the client, maintain the pre-wdp behaviour |
|
1100 // and write data immediately back to client (possibly taking a page fault) |
|
1101 // N.B. Must NOT do this on data paging media |
|
1202 #ifdef __DEMAND_PAGING__ |
1102 #ifdef __DEMAND_PAGING__ |
1203 else if (!DataPagingDfcQ(iDrive->iPrimaryMedia)) |
1103 else if (!DataPagingDfcQ(&aPrimaryMedia)) |
1204 #else |
1104 #else |
1205 else |
1105 else |
1206 #endif |
1106 #endif |
1207 { |
1107 { |
1208 Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL); |
1108 Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL); |
1209 } |
1109 } |
1210 pC->AsyncClose(); |
1110 pC->AsyncClose(); |
1111 } |
|
1211 } |
1112 } |
1212 OstTraceFunctionExit1( DLOCALDRIVE_NOTIFYCHANGE_EXIT, this ); |
1113 OstTraceFunctionExit1( DLOCALDRIVE_NOTIFYCHANGE_EXIT, this ); |
1213 } |
|
1214 |
|
1215 // This function is called by the primary media when a media change occurs |
|
1216 TInt DLocalDrive::MediaChangeCallback(TAny* aLocalDrive, TInt /* aNotifyType*/) |
|
1217 { |
|
1218 ((DLocalDrive*) aLocalDrive)->NotifyChange(); |
|
1219 return KErrNone; |
|
1220 } |
1114 } |
1221 |
1115 |
1222 TLocalDriveCleanup::TLocalDriveCleanup() |
1116 TLocalDriveCleanup::TLocalDriveCleanup() |
1223 { |
1117 { |
1224 } |
1118 } |
1235 NKern::UnlockSystem(); |
1129 NKern::UnlockSystem(); |
1236 pC->Close(NULL); // balances Open() in DoCreate |
1130 pC->Close(NULL); // balances Open() in DoCreate |
1237 NKern::LockSystem(); |
1131 NKern::LockSystem(); |
1238 } |
1132 } |
1239 |
1133 |
1240 |
|
1241 EXPORT_C TInt DLocalDrive::Caps(TInt aDriveNumber, TDes8& aCaps) |
|
1242 { |
|
1243 if(!Kern::CurrentThreadHasCapability(ECapabilityTCB,__PLATSEC_DIAGNOSTIC_STRING("Checked by ELOCD.LDD (Local Media Driver)"))) |
|
1244 { |
|
1245 return KErrPermissionDenied; |
|
1246 } |
|
1247 |
|
1248 |
|
1249 if (aDriveNumber >= KMaxLocalDrives) |
|
1250 return KErrArgument; |
|
1251 |
|
1252 TLocDrv* drive = TheDrives[aDriveNumber]; |
|
1253 if (!drive) |
|
1254 return KErrNotSupported; |
|
1255 |
|
1256 TLocDrvRequest request; |
|
1257 memclr(&request, sizeof(request)); |
|
1258 |
|
1259 request.Drive() = drive; |
|
1260 request.Id() = DLocalDrive::ECaps; |
|
1261 request.Length() = aCaps.Length(); |
|
1262 request.RemoteDes() = (TAny*) aCaps.Ptr(); |
|
1263 |
|
1264 return request.SendReceive(&drive->iPrimaryMedia->iMsgQ); |
|
1265 } |
|
1266 |
|
1267 /******************************************** |
1134 /******************************************** |
1268 * Local drive request class |
1135 * Local drive request class |
1269 ********************************************/ |
1136 ********************************************/ |
1270 |
1137 |
1271 /** |
1138 /** |
1290 */ |
1157 */ |
1291 EXPORT_C TInt TLocDrvRequest::ReadRemote(TDes8* aDes, TInt anOffset) |
1158 EXPORT_C TInt TLocDrvRequest::ReadRemote(TDes8* aDes, TInt anOffset) |
1292 { |
1159 { |
1293 OstTraceFunctionEntry1( TLOCDRVREQUEST_READREMOTE_ENTRY, this ); |
1160 OstTraceFunctionEntry1( TLOCDRVREQUEST_READREMOTE_ENTRY, this ); |
1294 TInt r; |
1161 TInt r; |
1295 |
|
1296 if (Flags() & TLocDrvRequest::EKernelBuffer) |
|
1297 { |
|
1298 (void)memcpy((TAny*) aDes->Ptr(), (TAny*)((TUint32)RemoteDes()+anOffset), aDes->MaxLength()); |
|
1299 aDes->SetLength(aDes->MaxLength()); |
|
1300 return KErrNone; |
|
1301 } |
|
1302 |
|
1303 DThread* pT=RemoteThread(); |
1162 DThread* pT=RemoteThread(); |
1304 if (!pT) |
1163 if (!pT) |
1305 pT=Client(); |
1164 pT=Client(); |
1306 |
1165 |
1307 #ifdef __DEMAND_PAGING__ // only if driver has its own thread, we don't support paging in MD which run in the context of their clients |
1166 #ifdef __DEMAND_PAGING__ // only if driver has its own thread, we don't support paging in MD which run in the context of their clients |
1437 */ |
1296 */ |
1438 EXPORT_C TInt TLocDrvRequest::WriteRemote(const TDesC8* aDes, TInt anOffset) |
1297 EXPORT_C TInt TLocDrvRequest::WriteRemote(const TDesC8* aDes, TInt anOffset) |
1439 { |
1298 { |
1440 OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITEREMOTE_ENTRY, this ); |
1299 OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITEREMOTE_ENTRY, this ); |
1441 TInt r; |
1300 TInt r; |
1442 |
|
1443 if (Flags() & TLocDrvRequest::EKernelBuffer) |
|
1444 { |
|
1445 (void)memcpy((TAny*)((TUint32)RemoteDes()+anOffset), (TAny*) aDes->Ptr(), aDes->Length()); |
|
1446 OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT1, this, KErrNone ); |
|
1447 return KErrNone; |
|
1448 } |
|
1449 |
|
1450 DThread* pC=Client(); |
1301 DThread* pC=Client(); |
1451 DThread* pT=RemoteThread(); |
1302 DThread* pT=RemoteThread(); |
1452 if (!pT) |
1303 if (!pT) |
1453 pT=pC; |
1304 pT=pC; |
1454 |
1305 |
1455 #ifdef __DEMAND_PAGING__ |
1306 #ifdef __DEMAND_PAGING__ |
1456 if (Flags() & ETClientBuffer) |
1307 if (Flags() & ETClientBuffer) |
1457 { |
1308 { |
1458 r = Kern::ThreadBufWrite(pT, (TClientBuffer*) RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC); |
1309 r = Kern::ThreadBufWrite(pT, (TClientBuffer*) RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC); |
1459 OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT2, this, r ); |
1310 OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT1, this, r ); |
1460 return r; |
1311 return r; |
1461 } |
1312 } |
1462 #endif |
1313 #endif |
1463 r = Kern::ThreadDesWrite(pT,RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC); |
1314 r = Kern::ThreadDesWrite(pT,RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC); |
1464 OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT3, this, r ); |
1315 OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT2, this, r ); |
1465 return r; |
1316 return r; |
1466 } |
1317 } |
1467 |
1318 |
1468 |
1319 |
1469 /** |
1320 /** |
1592 else |
1443 else |
1593 r = KErrNone; |
1444 r = KErrNone; |
1594 break; |
1445 break; |
1595 case DLocalDrive::EReduce: |
1446 case DLocalDrive::EReduce: |
1596 __KTRACE_OPT(KLOCDRV,Kern::Printf("Reduce request %lx@%lx",Length(),Pos())); |
1447 __KTRACE_OPT(KLOCDRV,Kern::Printf("Reduce request %lx@%lx",Length(),Pos())); |
1597 OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION3, "Reduce request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH (Pos()), (TUint) I64LOW (Pos()) ); |
1448 OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION3, "Reduce request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos()) ); |
1598 if (Pos()+Length()>d.iPartitionLen) |
1449 if (Pos()+Length()>d.iPartitionLen) |
1599 r = KErrArgument; |
1450 r = KErrArgument; |
1600 else |
1451 else |
1601 r = KErrNone; |
1452 r = KErrNone; |
1602 break; |
1453 break; |
1603 case DLocalDrive::EFormat: |
1454 case DLocalDrive::EFormat: |
1604 __KTRACE_OPT(KLOCDRV,Kern::Printf("Format request %lx@%lx",Length(),Pos())); |
1455 __KTRACE_OPT(KLOCDRV,Kern::Printf("Format request %lx@%lx",Length(),Pos())); |
1605 OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION4, "Format request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()),(TUint) I64LOW(Length()), (TUint) I64HIGH (Pos()), (TUint) I64LOW (Pos()) ); |
1456 OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION4, "Format request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()),(TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos()) ); |
1606 if (!(DriverFlags() & RLocalDrive::ELocDrvWholeMedia)) |
1457 if (!(DriverFlags() & RLocalDrive::ELocDrvWholeMedia)) |
1607 { |
1458 { |
1608 if (Pos()>d.iPartitionLen) |
1459 if (Pos()>d.iPartitionLen) |
1609 { |
1460 { |
1610 Length()=0; |
1461 Length()=0; |
1628 case DMediaPagingDevice::ERomPageInRequest: |
1479 case DMediaPagingDevice::ERomPageInRequest: |
1629 // if the ROM was reported to LOCM then it will also need to be adjusted.... |
1480 // if the ROM was reported to LOCM then it will also need to be adjusted.... |
1630 // Otherwise the media driver adjust it internally |
1481 // Otherwise the media driver adjust it internally |
1631 case DMediaPagingDevice::ECodePageInRequest: |
1482 case DMediaPagingDevice::ECodePageInRequest: |
1632 __KTRACE_OPT(KLOCDPAGING,Kern::Printf("Adjusted Paging read request %lx@%lx",Length(),Pos())); |
1483 __KTRACE_OPT(KLOCDPAGING,Kern::Printf("Adjusted Paging read request %lx@%lx",Length(),Pos())); |
1633 OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, TLOCDRVREQUESTCHECKANDADJUSTFORPARTITION5, "Adjusted Paging read request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos())); |
1484 OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, TLOCDRVREQUESTCHECKANDADJUSTFORPARTITION5, "Adjusted Paging read request length=%x:%x; position=%x%:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos())); |
1634 if (Pos()+Length()>d.iPartitionLen) |
1485 if (Pos()+Length()>d.iPartitionLen) |
1635 { |
1486 { |
1636 r = KErrArgument; |
1487 r = KErrArgument; |
1637 break; |
1488 break; |
1638 } |
1489 } |
1641 break; |
1492 break; |
1642 #endif |
1493 #endif |
1643 |
1494 |
1644 default: // read or write or fragment |
1495 default: // read or write or fragment |
1645 __KTRACE_OPT(KLOCDRV,Kern::Printf("R/W request %lx@%lx",Length(),Pos())); |
1496 __KTRACE_OPT(KLOCDRV,Kern::Printf("R/W request %lx@%lx",Length(),Pos())); |
1646 OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION6, "Read/Write request length=%x:%x; position=%x:%x", (TUint)I64HIGH (Length()), (TUint)I64LOW (Length()), (TUint) I64HIGH (Pos()), (TUint) I64LOW (Pos())); |
1497 OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION6, "Read/Write request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos())); |
1647 if (DriverFlags() & RLocalDrive::ELocDrvWholeMedia) |
1498 if (DriverFlags() & RLocalDrive::ELocDrvWholeMedia) |
1648 { |
1499 { |
1649 if (d.iMedia && d.iMedia->iDriver && Pos()+Length() > d.iMedia->iPartitionInfo.iMediaSizeInBytes) |
1500 if (d.iMedia && d.iMedia->iDriver && Pos()+Length() > d.iMedia->iDriver->iTotalSizeInBytes) |
1650 { |
1501 { |
1651 r = KErrArgument; |
1502 r = KErrArgument; |
1652 break; |
1503 break; |
1653 } |
1504 } |
1654 } |
1505 } |
1674 { |
1525 { |
1675 OstTraceFunctionEntryExt( TLOCDRV_TLOCDRV_ENTRY, this ); |
1526 OstTraceFunctionEntryExt( TLOCDRV_TLOCDRV_ENTRY, this ); |
1676 memclr(this, sizeof(TLocDrv)); |
1527 memclr(this, sizeof(TLocDrv)); |
1677 iDriveNumber=aDriveNumber; |
1528 iDriveNumber=aDriveNumber; |
1678 iPartitionNumber=-1; |
1529 iPartitionNumber=-1; |
1679 iMediaChangeObserver.iFunction = MediaChangeCallback; |
|
1680 iMediaChangeObserver.iPtr= this; |
|
1681 iMediaChangeObserver.iObjectType = TCallBackLink::ETLocDrvObject; |
|
1682 OstTraceFunctionExit1( TLOCDRV_TLOCDRV_EXIT, this ); |
1530 OstTraceFunctionExit1( TLOCDRV_TLOCDRV_EXIT, this ); |
1683 } |
1531 } |
1684 |
|
1685 TInt TLocDrv::MediaChangeCallback(TAny* aLocDrv, TInt aNotifyType) |
|
1686 { |
|
1687 __ASSERT_DEBUG(aNotifyType == DPrimaryMediaBase::EMediaChange || aNotifyType == DPrimaryMediaBase::EMediaPresent, LOCM_FAULT()); |
|
1688 if (aNotifyType == DPrimaryMediaBase::EMediaPresent) |
|
1689 return ((TLocDrv*) aLocDrv)->iPrimaryMedia->iBody->iMediaPresentDfc.Enque(); |
|
1690 else |
|
1691 return ((TLocDrv*) aLocDrv)->iPrimaryMedia->iBody->iMediaChangeDfc.Enque(); |
|
1692 } |
|
1693 |
|
1694 |
1532 |
1695 /** |
1533 /** |
1696 Initialises the DMedia entity with the media device number and ID. |
1534 Initialises the DMedia entity with the media device number and ID. |
1697 |
1535 |
1698 @param aDevice The unique ID for this device. This can take one of the |
1536 @param aDevice The unique ID for this device. This can take one of the |
1754 } |
1592 } |
1755 |
1593 |
1756 |
1594 |
1757 primaryMedia->iMsgQ.Receive(); // allow reception of more messages |
1595 primaryMedia->iMsgQ.Receive(); // allow reception of more messages |
1758 OstTraceFunctionExit0( _HANDLEMSG_EXIT ); |
1596 OstTraceFunctionExit0( _HANDLEMSG_EXIT ); |
1759 } |
|
1760 |
|
1761 |
|
1762 void mediaChangeDfc(TAny* aPtr) |
|
1763 { |
|
1764 DPrimaryMediaBase* pM = (DPrimaryMediaBase*)aPtr; |
|
1765 pM->NotifyMediaChange(); |
|
1766 } |
|
1767 |
|
1768 void mediaPresentDfc(TAny* aPtr) |
|
1769 { |
|
1770 DPrimaryMediaBase* pM = (DPrimaryMediaBase*)aPtr; |
|
1771 pM->NotifyMediaPresent(); |
|
1772 } |
|
1773 |
|
1774 DPrimaryMediaBase::DBody::DBody(DPrimaryMediaBase& aPrimaryMediaBase) : |
|
1775 iPrimaryMediaBase(aPrimaryMediaBase), |
|
1776 iMediaChangeDfc(mediaChangeDfc, &aPrimaryMediaBase, KMaxDfcPriority), |
|
1777 iMediaPresentDfc(mediaPresentDfc, &aPrimaryMediaBase, KMaxDfcPriority) |
|
1778 { |
|
1779 } |
1597 } |
1780 |
1598 |
1781 EXPORT_C DPrimaryMediaBase::DPrimaryMediaBase() |
1599 EXPORT_C DPrimaryMediaBase::DPrimaryMediaBase() |
1782 : iMsgQ(handleMsg, this, NULL, 1), |
1600 : iMsgQ(handleMsg, this, NULL, 1), |
1783 iDeferred(NULL, NULL, NULL, 0), // callback never used |
1601 iDeferred(NULL, NULL, NULL, 0), // callback never used |
1815 |
1633 |
1816 if (r != KErrNone) |
1634 if (r != KErrNone) |
1817 { |
1635 { |
1818 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT1, this, r ); |
1636 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT1, this, r ); |
1819 return r; |
1637 return r; |
1820 } |
1638 } |
1821 iBody = new DBody(*this); |
1639 iBody = new DBody; |
1822 if (iBody == NULL) |
1640 if (iBody == NULL) |
1823 { |
1641 { |
1824 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT2, this, KErrNoMemory ); |
1642 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT2, this, KErrNoMemory ); |
1825 return KErrNoMemory; |
1643 return KErrNoMemory; |
1826 } |
1644 } |
1827 if (iDfcQ) |
1645 |
1828 { |
1646 |
1829 iBody->iMediaChangeDfc.SetDfcQ(iDfcQ); |
|
1830 iBody->iMediaPresentDfc.SetDfcQ(iDfcQ); |
|
1831 } |
|
1832 |
1647 |
1833 #ifdef __DEMAND_PAGING__ |
1648 #ifdef __DEMAND_PAGING__ |
1834 TInt pageSize = Kern::RoundToPageSize(1); |
1649 TInt pageSize = Kern::RoundToPageSize(1); |
1835 iBody->iPageSizeMsk = pageSize-1; |
1650 iBody->iPageSizeMsk = pageSize-1; |
1836 iBody->iPageSizeLog2 = __e32_find_ms1_32(pageSize); |
1651 iBody->iPageSizeLog2 = __e32_find_ms1_32(pageSize); |
1889 // If this is the first connection, open media driver now |
1704 // If this is the first connection, open media driver now |
1890 // Assume no non-primary media exist on this device |
1705 // Assume no non-primary media exist on this device |
1891 |
1706 |
1892 NKern::LockSystem(); |
1707 NKern::LockSystem(); |
1893 TBool first=iConnectionQ.IsEmpty(); |
1708 TBool first=iConnectionQ.IsEmpty(); |
1894 iConnectionQ.Add(&aLocalDrive->iMediaChangeObserver.iLink); |
1709 iConnectionQ.Add(&aLocalDrive->iLink); |
1895 NKern::UnlockSystem(); |
1710 NKern::UnlockSystem(); |
1896 if (first) |
1711 if (first) |
1897 { |
1712 { |
1898 r=OpenMediaDriver(); |
1713 r=OpenMediaDriver(); |
1899 if (r!=KErrNone) |
1714 if (r!=KErrNone) |
1957 if (pD) |
1772 if (pD) |
1958 pD->Close(); |
1773 pD->Close(); |
1959 OstTraceFunctionExit1( DPRIMARYMEDIABASE_DISCONNECT_EXIT2, this ); |
1774 OstTraceFunctionExit1( DPRIMARYMEDIABASE_DISCONNECT_EXIT2, this ); |
1960 } |
1775 } |
1961 |
1776 |
1962 |
|
1963 /** |
|
1964 Connects a TLocDrv containing a media extension to the next primary media in the chain |
|
1965 */ |
|
1966 TInt DPrimaryMediaBase::Connect(TLocDrv* aLocDrv) |
|
1967 { |
|
1968 TInt r = KErrNone; |
|
1969 |
|
1970 NKern::LockSystem(); |
|
1971 TBool first = iConnectionQ.IsEmpty(); |
|
1972 iConnectionQ.Add(&aLocDrv->iMediaChangeObserver.iLink); |
|
1973 NKern::UnlockSystem(); |
|
1974 |
|
1975 if (first && !iDfcQ) |
|
1976 { |
|
1977 r = OpenMediaDriver(); |
|
1978 if (r!=KErrNone) |
|
1979 { |
|
1980 NKern::LockSystem(); |
|
1981 aLocDrv->iMediaChangeObserver.iLink.Deque(); |
|
1982 NKern::UnlockSystem(); |
|
1983 } |
|
1984 } |
|
1985 return r; |
|
1986 } |
|
1987 |
|
1988 TInt DPrimaryMediaBase::HandleMediaNotPresent(TLocDrvRequest& aReq) |
|
1989 { |
|
1990 TInt reqId = aReq.Id(); |
|
1991 |
|
1992 if (reqId == DLocalDrive::ECaps) |
|
1993 DefaultDriveCaps(*(TLocalDriveCapsV2*)aReq.RemoteDes()); // fill in stuff we know even if no media present |
|
1994 |
|
1995 TInt r = QuickCheckStatus(); |
|
1996 if (r != KErrNone && |
|
1997 reqId != DLocalDrive::EForceMediaChange && // EForceMediaChange, and |
|
1998 reqId != DLocalDrive::EReadPasswordStore && // Password store operations |
|
1999 reqId != DLocalDrive::EWritePasswordStore && // do not require the media |
|
2000 reqId != DLocalDrive::EPasswordStoreLengthInBytes) // to be ready.) |
|
2001 { |
|
2002 return r; |
|
2003 } |
|
2004 |
|
2005 return KErrNone; |
|
2006 } |
|
2007 |
|
2008 EXPORT_C TInt DPrimaryMediaBase::Request(TLocDrvRequest& aReq) |
1777 EXPORT_C TInt DPrimaryMediaBase::Request(TLocDrvRequest& aReq) |
2009 /** |
1778 /** |
2010 Issues a local drive request. It is called from TLocDrv::Request() function . |
1779 Issues a local drive request. It is called from TLocDrv::Request() function . |
2011 Each local drive request is encapsulated as a TLocDrvRequest- a class derived from TThreadMessage, the kernel message class. |
1780 Each local drive request is encapsulated as a TLocDrvRequest- a class derived from TThreadMessage, the kernel message class. |
2012 TLocDrvRequest contains information pertaining to the request, including the ID and any associated parameters such as drive position, length and source/destination location. |
1781 TLocDrvRequest contains information pertaining to the request, including the ID and any associated parameters such as drive position, length and source/destination location. |
2023 Otherwise, one of the other system wide error codes. |
1792 Otherwise, one of the other system wide error codes. |
2024 |
1793 |
2025 @see TLocDrvRequest |
1794 @see TLocDrvRequest |
2026 */ |
1795 */ |
2027 { |
1796 { |
2028 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this ); |
1797 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this ); |
2029 |
1798 |
2030 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::Request(%08x)",iMediaId,&aReq)); |
1799 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::Request(%08x)",iMediaId,&aReq)); |
2031 __KTRACE_OPT(KLOCDRV,Kern::Printf("this=%x, ReqId=%d, Pos=%lx, Len=%lx, remote thread %O",this,aReq.Id(),aReq.Pos(),aReq.Length(),aReq.RemoteThread())); |
1800 __KTRACE_OPT(KLOCDRV,Kern::Printf("this=%x, ReqId=%d, Pos=%lx, Len=%lx, remote thread %O",this,aReq.Id(),aReq.Pos(),aReq.Length(),aReq.RemoteThread())); |
2032 |
1801 |
2033 OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST, "reqId=%d; remote thread=0x%x", (TInt) aReq.Id(), (TUint) aReq.RemoteThread()); |
1802 OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST, "reqId=%d; remote thread=0x%x", (TInt) aReq.Id(), (TUint) aReq.RemoteThread()); |
2034 OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST2, "length=%x:%x; position=%x:%x", (TUint) I64HIGH(aReq.Length()), (TUint) I64LOW(aReq.Length()), (TUint) I64HIGH(aReq.Pos()), (TUint) I64LOW(aReq.Pos())); |
1803 OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST2, "length=%x:%x; position=%x:%x", (TUint) I64HIGH(aReq.Length()), (TUint) I64LOW(aReq.Length()), (TUint) I64HIGH(aReq.Pos()), (TUint) I64LOW(aReq.Pos())); |
2035 |
1804 |
2036 TInt reqId = aReq.Id(); |
1805 TInt reqId = aReq.Id(); |
2037 |
1806 |
2038 TInt r = HandleMediaNotPresent(aReq); |
1807 if (reqId == DLocalDrive::ECaps) |
2039 if (r != KErrNone) |
1808 DefaultDriveCaps(*(TLocalDriveCapsV2*)aReq.RemoteDes()); // fill in stuff we know even if no media present |
2040 { |
1809 |
1810 TInt r = QuickCheckStatus(); |
|
1811 if (r != KErrNone && aReq.Id()!=DLocalDrive::EForceMediaChange && // EForceMediaChange, and |
|
1812 aReq.Id()!=DLocalDrive::EReadPasswordStore && // Password store operations |
|
1813 aReq.Id()!=DLocalDrive::EWritePasswordStore && // do not require the media |
|
1814 aReq.Id()!=DLocalDrive::EPasswordStoreLengthInBytes) // to be ready.) |
|
1815 { |
|
2041 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_REQUEST_EXIT, this, r ); |
1816 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_REQUEST_EXIT, this, r ); |
2042 return r; |
1817 return r; |
2043 } |
1818 } |
2044 |
|
2045 |
1819 |
2046 |
1820 |
2047 // for ERead & EWrite requests, get the linear address for pinning & DMA |
1821 // for ERead & EWrite requests, get the linear address for pinning & DMA |
2048 TUint8* linAddress = NULL; |
1822 TUint8* linAddress = NULL; |
2049 TClientBuffer clientBuffer; |
1823 TClientBuffer clientBuffer; |
2485 switch (m.iValue) |
2259 switch (m.iValue) |
2486 { |
2260 { |
2487 case EConnect: |
2261 case EConnect: |
2488 { |
2262 { |
2489 DLocalDrive* pD=(DLocalDrive*)m.Ptr0(); |
2263 DLocalDrive* pD=(DLocalDrive*)m.Ptr0(); |
2490 iConnectionQ.Add(&pD->iMediaChangeObserver.iLink); |
2264 iConnectionQ.Add(&pD->iLink); |
2491 m.Complete(KErrNone, EFalse); |
2265 m.Complete(KErrNone, EFalse); |
2492 OstTraceFunctionExit1( DPRIMARYMEDIABASE_HANDLEMSG_EXIT1, this ); |
2266 OstTraceFunctionExit1( DPRIMARYMEDIABASE_HANDLEMSG_EXIT1, this ); |
2493 return; |
2267 return; |
2494 } |
2268 } |
2495 case EDisconnect: |
2269 case EDisconnect: |
2508 return; |
2282 return; |
2509 } |
2283 } |
2510 case DLocalDrive::EForceMediaChange: |
2284 case DLocalDrive::EForceMediaChange: |
2511 { |
2285 { |
2512 TUint flags = (TUint) m.Pos(); |
2286 TUint flags = (TUint) m.Pos(); |
2513 |
|
2514 #ifdef __DEMAND_PAGING__ |
|
2515 // if this is a paging media (ROM,code or data), turn off the KMediaRemountForceMediaChange flag |
|
2516 // as this normally results in a call to DPBusSocket::ForceMediaChange() which effectively disables |
|
2517 // the media for a small time period - which would be disasterous if a paging request arrived |
|
2518 if (iBody->iPagingDevice) |
|
2519 flags&= ~KMediaRemountForceMediaChange; |
|
2520 #endif |
|
2521 |
|
2522 // For media extension drivers, send a copy of the request to the next drive in the chain and wait for it. |
|
2523 TLocDrv* drv = m.Drive(); |
|
2524 if (drv->iNextDrive) |
|
2525 { |
|
2526 TLocDrvRequest request; |
|
2527 request.Drive() = drv->iNextDrive; |
|
2528 request.Id() = DLocalDrive::EForceMediaChange; |
|
2529 request.Pos() = m.Pos(); // flags |
|
2530 |
|
2531 request.SendReceive(&drv->iNextDrive->iPrimaryMedia->iMsgQ); |
|
2532 |
|
2533 CompleteRequest(m, request.iValue); |
|
2534 return; |
|
2535 } |
|
2536 |
|
2537 |
2287 |
2538 // if KForceMediaChangeReOpenDriver specified wait for power up, |
2288 // if KForceMediaChangeReOpenDriver specified wait for power up, |
2539 // and then re-open this drive's media driver |
2289 // and then re-open this drive's media driver |
2540 __KTRACE_OPT(KLOCDRV, Kern::Printf("EForceMediaChange, flags %08X\n", flags)); |
2290 __KTRACE_OPT(KLOCDRV, Kern::Printf("EForceMediaChange, flags %08X\n", flags)); |
2541 if (flags == (TUint) KForceMediaChangeReOpenMediaDriver) |
2291 if (flags == (TUint) KForceMediaChangeReOpenMediaDriver) |
2763 |
2513 |
2764 // re-open this drive's media driver ? |
2514 // re-open this drive's media driver ? |
2765 if (m.iValue == DLocalDrive::EForceMediaChange) |
2515 if (m.iValue == DLocalDrive::EForceMediaChange) |
2766 { |
2516 { |
2767 __ASSERT_DEBUG(((TUint) m.Pos()) == (TUint) KForceMediaChangeReOpenMediaDriver, LOCM_FAULT()); |
2517 __ASSERT_DEBUG(((TUint) m.Pos()) == (TUint) KForceMediaChangeReOpenMediaDriver, LOCM_FAULT()); |
2518 |
|
2768 iCurrentReq=NULL; |
2519 iCurrentReq=NULL; |
2769 |
2520 |
2770 TLocDrv* pL = m.Drive(); |
2521 TLocDrv* pL = m.Drive(); |
2771 DMedia* media = pL->iMedia; |
2522 DMedia* media = pL->iMedia; |
2772 |
|
2773 if (media && media->iDriver) |
2523 if (media && media->iDriver) |
2774 CloseMediaDrivers(media); |
2524 CloseMediaDrivers(media); |
2775 |
2525 |
2776 iState=EOpening; |
2526 iState=EOpening; |
2777 StartOpenMediaDrivers(); |
2527 StartOpenMediaDrivers(); |
2778 |
2528 |
2779 NotifyClients(EMediaChange, pL); |
2529 NotifyClients(ETrue,pL); |
2780 CompleteRequest(m, r); |
2530 CompleteRequest(m, r); |
2781 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT, this, r ); |
2531 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT, this, r ); |
2782 return r; |
2532 return r; |
2783 } |
2533 } |
2784 |
2534 |
2801 return KErrNone; |
2551 return KErrNone; |
2802 } |
2552 } |
2803 if (!(m.Flags() & TLocDrvRequest::EAdjusted)) |
2553 if (!(m.Flags() & TLocDrvRequest::EAdjusted)) |
2804 { |
2554 { |
2805 // If this isn't the only partition, don't allow access to the whole media |
2555 // If this isn't the only partition, don't allow access to the whole media |
2806 if (TDriveIterator::GetPhysicalDrive(m.Drive())->iPrimaryMedia->iTotalPartitionsOpened > 1) |
2556 if (iTotalPartitionsOpened > 1) |
2807 m.DriverFlags() &= ~RLocalDrive::ELocDrvWholeMedia; |
2557 m.DriverFlags() &= ~RLocalDrive::ELocDrvWholeMedia; |
2808 r=m.CheckAndAdjustForPartition(); |
2558 r=m.CheckAndAdjustForPartition(); |
2809 } |
2559 } |
2810 if (r==KErrNone) |
2560 if (r==KErrNone) |
2811 { |
2561 { |
2887 OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOREQUEST4, "Media driver cannot service or defer PageIn request 0x%08x or serviced it synchronously; retval=%d",(TUint) &m, s); |
2637 OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOREQUEST4, "Media driver cannot service or defer PageIn request 0x%08x or serviced it synchronously; retval=%d",(TUint) &m, s); |
2888 iBody->iPagingDevice->CompleteRequest(&m, s); |
2638 iBody->iPagingDevice->CompleteRequest(&m, s); |
2889 } |
2639 } |
2890 else |
2640 else |
2891 #endif |
2641 #endif |
2892 { |
2642 |
2893 CompleteRequest(m, s); |
2643 CompleteRequest(m, s); |
2894 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_INTERNALS, DPRIMARYMEDIABASE_DOREQUEST_RETURN, "Return Remote Thread=0x%x; retval=%d", (TUint) m.RemoteThread(), (TInt) s); |
2644 OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_INTERNALS, DPRIMARYMEDIABASE_DOREQUEST_RETURN, "Return req Id=%d; Remote Thread=0x%x; retval=%d", (TInt) m.Id(), (TUint) m.RemoteThread(), (TInt) s); |
2895 } |
|
2896 } |
2645 } |
2897 |
2646 |
2898 iCurrentReq=NULL; |
2647 iCurrentReq=NULL; |
2899 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT3, this, r ); |
2648 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT3, this, r ); |
2900 return r; |
2649 return r; |
2946 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS1, "DPrimaryMediaBase iMediaId=%d", iMediaId ); |
2695 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS1, "DPrimaryMediaBase iMediaId=%d", iMediaId ); |
2947 |
2696 |
2948 // we mustn't ever close the media driver if it's responsible for data paging as re-opening the drive |
2697 // we mustn't ever close the media driver if it's responsible for data paging as re-opening the drive |
2949 // would involve memory allocation which might cause deadlock if the kernel heap were to grow |
2698 // would involve memory allocation which might cause deadlock if the kernel heap were to grow |
2950 #ifdef __DEMAND_PAGING__ |
2699 #ifdef __DEMAND_PAGING__ |
2951 if (DataPagingMedia(this)) |
2700 if (DataPagingDfcQ(this)) |
2952 { |
2701 { |
2953 __KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for data paging media %08X", this)); |
2702 __KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for data paging media %08X", this)); |
2954 OstTrace1(TRACE_FLOW, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS_EXIT1, "CloseMediaDrivers aborting for data paging media 0x%08x", this); |
2703 OstTrace1(TRACE_FLOW, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS_EXIT1, "CloseMediaDrivers aborting for data paging media 0x%08x", this); |
2955 return; |
2704 return; |
2956 } |
2705 } |
2957 #endif |
2706 #endif |
2958 |
2707 |
2959 |
2708 TInt i; |
2960 // Don't close any media extension drivers either, since it won't serve any purpose |
2709 for (i=0; i<KMaxLocalDrives; i++) |
2961 // and keeping the driver open allows it to maintain internal state |
2710 { |
2962 if (iBody->iMediaExtension) |
2711 TLocDrv* pL=TheDrives[i]; |
2963 { |
|
2964 __KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for extension media %08X", this)); |
|
2965 return; |
|
2966 } |
|
2967 |
|
2968 |
|
2969 TDriveIterator driveIter; |
|
2970 for (TLocDrv* pL = driveIter.NextDrive(); pL != NULL; pL = driveIter.NextDrive()) |
|
2971 { |
|
2972 if (pL && pL->iPrimaryMedia==this) |
2712 if (pL && pL->iPrimaryMedia==this) |
2973 { |
2713 { |
2974 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",driveIter.Index())); |
2714 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",i)); |
2975 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", driveIter.Index()); |
2715 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", i ); |
2976 if (aMedia == NULL || pL->iMedia == aMedia) |
2716 if (aMedia == NULL || pL->iMedia == aMedia) |
2977 { |
2717 { |
2978 pL->iMedia=NULL; |
2718 pL->iMedia=NULL; |
2979 } |
2719 } |
2980 } |
2720 } |
2981 } |
2721 } |
2982 for (TInt i=iLastMediaId; i>=iMediaId; i--) |
2722 for (i=iLastMediaId; i>=iMediaId; i--) |
2983 { |
2723 { |
2984 DMedia* pM=TheMedia[i]; |
2724 DMedia* pM=TheMedia[i]; |
2985 if (aMedia == NULL || pM == aMedia) |
2725 if (aMedia == NULL || pM == aMedia) |
2986 { |
2726 { |
2987 DMediaDriver* pD=pM->iDriver; |
2727 DMediaDriver* pD=pM->iDriver; |
3134 { |
2874 { |
3135 // couldn't read partition info or driver failed to open |
2875 // couldn't read partition info or driver failed to open |
3136 if (pM->iDriver) |
2876 if (pM->iDriver) |
3137 { |
2877 { |
3138 #ifdef __DEMAND_PAGING__ |
2878 #ifdef __DEMAND_PAGING__ |
3139 if (DataPagingMedia(this)) |
2879 if (DataPagingDfcQ(this)) |
3140 { |
2880 { |
3141 __KTRACE_OPT(KLOCDRV,Kern::Printf("DoPartitionInfoComplete(%d) Close Media Driver aborted for data paging media %08X", this)); |
2881 __KTRACE_OPT(KLOCDRV,Kern::Printf("DoPartitionInfoComplete(%d) Close Media Driver aborted for data paging media %08X", this)); |
3142 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE2, "Close Media Driver for data paging media 0x%08x", this); |
2882 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE2, "Close Media Driver for data paging media 0x%08x", this); |
3143 } |
2883 } |
3144 else |
2884 else |
3200 // work out mapping of drives to partitions/media |
2940 // work out mapping of drives to partitions/media |
3201 TInt totalPartitions=iTotalPartitionsOpened; |
2941 TInt totalPartitions=iTotalPartitionsOpened; |
3202 TInt id=iMediaId; // start with primary media |
2942 TInt id=iMediaId; // start with primary media |
3203 TInt partitionsOnThisMedia=PartitionCount(); |
2943 TInt partitionsOnThisMedia=PartitionCount(); |
3204 TInt partition=0; |
2944 TInt partition=0; |
3205 |
2945 TInt j; |
3206 TDriveIterator driveIter; |
2946 for (j=0; j<KMaxLocalDrives; j++) |
3207 for (TLocDrv* pD = driveIter.NextDrive(); pD != NULL; pD = driveIter.NextDrive()) |
2947 { |
3208 { |
2948 TLocDrv* pD=TheDrives[j]; |
3209 if (pD && pD->iPrimaryMedia==this) |
2949 if (pD && pD->iPrimaryMedia==this) |
3210 { |
2950 { |
3211 if (totalPartitions==0) |
2951 if (totalPartitions==0) |
3212 { |
2952 { |
3213 pD->iMedia=NULL; |
2953 pD->iMedia=NULL; |
3217 { |
2957 { |
3218 id++; |
2958 id++; |
3219 partition=0; |
2959 partition=0; |
3220 partitionsOnThisMedia=TheMedia[id]->PartitionCount(); |
2960 partitionsOnThisMedia=TheMedia[id]->PartitionCount(); |
3221 } |
2961 } |
3222 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d = Media %d Partition %d",driveIter.Index(),id,partition)); |
2962 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d = Media %d Partition %d",j,id,partition)); |
3223 OstTraceExt3( TRACE_INTERNALS, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE5, "Local Drive=%d; iMediaId=%d; partition=%d", driveIter.Index(), id, partition ); |
2963 OstTraceExt3( TRACE_INTERNALS, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE5, "Local Drive=%d; iMediaId=%d; partition=%d", j, id, partition ); |
2964 |
|
3224 pD->iMedia=TheMedia[id]; |
2965 pD->iMedia=TheMedia[id]; |
3225 pD->iPartitionNumber=partition; |
2966 pD->iPartitionNumber=partition; |
3226 memcpy(pD, pD->iMedia->iPartitionInfo.iEntry+partition, sizeof(TPartitionEntry)); |
2967 memcpy(pD, pD->iMedia->iPartitionInfo.iEntry+partition, sizeof(TPartitionEntry)); |
3227 partition++; |
2968 partition++; |
3228 totalPartitions--; |
2969 totalPartitions--; |
3484 |
3225 |
3485 iWaitMedChg.CompleteAll(KErrNone); |
3226 iWaitMedChg.CompleteAll(KErrNone); |
3486 OstTraceFunctionExit1( DPRIMARYMEDIABASE_SETCLOSED_EXIT, this ); |
3227 OstTraceFunctionExit1( DPRIMARYMEDIABASE_SETCLOSED_EXIT, this ); |
3487 } |
3228 } |
3488 |
3229 |
3489 void DPrimaryMediaBase::NotifyClients(TNotifyType aNotifyType, TLocDrv* aLocDrv) |
3230 void DPrimaryMediaBase::NotifyClients(TBool aMediaChange,TLocDrv* aLocDrv) |
3490 |
3231 |
3491 // |
3232 // |
3492 // Notify all clients of a media change or media present event |
3233 // Notify all clients of a media change or power-down event |
3493 // |
3234 // |
3494 { |
3235 { |
3495 OstTraceFunctionEntryExt( DPRIMARYMEDIABASE_NOTIFYCLIENTS_ENTRY, this ); |
3236 OstTraceFunctionEntryExt( DPRIMARYMEDIABASE_NOTIFYCLIENTS_ENTRY, this ); |
3496 |
3237 |
3497 SDblQueLink* pL=iConnectionQ.iA.iNext; |
3238 SDblQueLink* pL=iConnectionQ.iA.iNext; |
3498 while (pL!=&iConnectionQ.iA) |
3239 while (pL!=&iConnectionQ.iA) |
3499 { |
3240 { |
3500 // Get pointer to TCallBackLink |
3241 DLocalDrive* pD=_LOFF(pL,DLocalDrive,iLink); |
3501 TCallBackLink* pCallBackLink = _LOFF(pL,TCallBackLink,iLink); |
|
3502 |
|
3503 // The link is embedded in either a TLocDrv or a DLocalDrive object; |
|
3504 // find out which one it is and then get TLocDrv pointer from that |
|
3505 __ASSERT_DEBUG(pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject || pCallBackLink->iObjectType == TCallBackLink::ETLocDrvObject, LOCM_FAULT()); |
|
3506 TLocDrv* locDrv; |
|
3507 if (pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject) |
|
3508 locDrv = ((DLocalDrive*) _LOFF(pCallBackLink,DLocalDrive, iMediaChangeObserver))->iDrive; |
|
3509 else |
|
3510 locDrv = ((TLocDrv*) _LOFF(pCallBackLink,TLocDrv, iMediaChangeObserver))->iNextDrive; |
|
3511 |
|
3512 // Issue the notification if the caller wants to notify all drives (aLocDrv == NULL) or |
3242 // Issue the notification if the caller wants to notify all drives (aLocDrv == NULL) or |
3513 // the specified drive matches this one |
3243 // the specified drive matches this one |
3514 if (aLocDrv == NULL || aLocDrv == locDrv) |
3244 if (aLocDrv == NULL || aLocDrv == pD->iDrive) |
3515 pCallBackLink->CallBack(aNotifyType); |
3245 pD->NotifyChange(*this, aMediaChange); |
3516 |
|
3517 pL=pL->iNext; |
3246 pL=pL->iNext; |
3518 } |
3247 } |
3519 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYCLIENTS_EXIT, this ); |
3248 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYCLIENTS_EXIT, this ); |
3520 } |
3249 } |
3521 |
3250 |
3529 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_ENTRY, this ); |
3258 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_ENTRY, this ); |
3530 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaChange state %d",iMediaId,iState)); |
3259 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaChange state %d",iMediaId,iState)); |
3531 |
3260 |
3532 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE, "iMediaId=%d; iState=%d", iMediaId, iState ); |
3261 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE, "iMediaId=%d; iState=%d", iMediaId, iState ); |
3533 |
3262 |
3534 // This should only be called in the context of the media thread |
3263 TInt state=iState; |
3535 __ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT()); |
3264 |
3536 |
3265 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
3537 MediaChange(); |
3266 |
3267 #ifdef __DEMAND_PAGING__ |
|
3268 iBody->iMediaChanges++; |
|
3269 |
|
3270 // As data paging media never close, need to ensure the media driver cancels |
|
3271 // any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange(). |
|
3272 // DMediaDriver::NotifyPowerDown() should do this |
|
3273 if(DataPagingDfcQ(this)) |
|
3274 NotifyPowerDown(); |
|
3275 #endif |
|
3276 |
|
3277 // complete any outstanding requests with KErrNotReady |
|
3278 // and any force media change requests with KErrNone |
|
3279 SetClosed(KErrNotReady); |
|
3280 |
|
3281 // close all media drivers on this device |
|
3282 if (state>=EOpening) |
|
3283 { |
|
3284 CloseMediaDrivers(); |
|
3285 } |
|
3538 |
3286 |
3539 // notify all connections that media change has occurred |
3287 // notify all connections that media change has occurred |
3540 NotifyClients(EMediaChange); |
3288 NotifyClients(ETrue); |
3541 |
3289 |
3542 // complete any force media change requests |
3290 // complete any force media change requests |
3543 iWaitMedChg.CompleteAll(KErrNone); |
3291 iWaitMedChg.CompleteAll(KErrNone); |
3544 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_EXIT, this ); |
3292 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_EXIT, this ); |
3545 } |
3293 } |
3604 else |
3352 else |
3605 { |
3353 { |
3606 CloseMediaDrivers(); |
3354 CloseMediaDrivers(); |
3607 SetClosed(KErrNotReady); |
3355 SetClosed(KErrNotReady); |
3608 } |
3356 } |
3357 |
|
3358 NotifyClients(EFalse); |
|
3609 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYPOWERDOWN_EXIT, this ); |
3359 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYPOWERDOWN_EXIT, this ); |
3610 } |
3360 } |
3611 |
3361 |
3612 |
3362 |
3613 EXPORT_C void DPrimaryMediaBase::NotifyPsuFault(TInt anError) |
3363 EXPORT_C void DPrimaryMediaBase::NotifyPsuFault(TInt anError) |
3673 // if ready, media driver should complete current request |
3423 // if ready, media driver should complete current request |
3674 CompleteCurrent(KErrNotReady); |
3424 CompleteCurrent(KErrNotReady); |
3675 } |
3425 } |
3676 CloseMediaDrivers(); |
3426 CloseMediaDrivers(); |
3677 SetClosed(KErrNotReady); |
3427 SetClosed(KErrNotReady); |
3428 NotifyClients(EFalse); |
|
3678 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYEMERGENCYPOWERDOWN_EXIT, this ); |
3429 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYEMERGENCYPOWERDOWN_EXIT, this ); |
3679 } |
|
3680 |
|
3681 |
|
3682 /** |
|
3683 Called by NotifyMediaPresent() and NotifyMediaChange() to ensure the media is in the correct state |
|
3684 */ |
|
3685 void DPrimaryMediaBase::MediaChange() |
|
3686 { |
|
3687 // Media has been inserted, so we need to cancel any outstanding requests and |
|
3688 // ensure that the partition info is read again |
|
3689 TInt state = iState; |
|
3690 |
|
3691 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
|
3692 |
|
3693 #ifdef __DEMAND_PAGING__ |
|
3694 iBody->iMediaChanges++; |
|
3695 |
|
3696 // As data paging media never close, need to ensure the media driver cancels |
|
3697 // any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange(). |
|
3698 // DMediaDriver::NotifyPowerDown() should do this |
|
3699 if (DataPagingMedia(this)) |
|
3700 NotifyPowerDown(); |
|
3701 #endif |
|
3702 |
|
3703 // complete any outstanding requests with KErrNotReady |
|
3704 // and any force media change requests with KErrNone |
|
3705 SetClosed(KErrNotReady); |
|
3706 |
|
3707 // close all media drivers on this device |
|
3708 if (state>=EOpening) |
|
3709 { |
|
3710 CloseMediaDrivers(); |
|
3711 } |
|
3712 } |
3430 } |
3713 |
3431 |
3714 EXPORT_C void DPrimaryMediaBase::NotifyMediaPresent() |
3432 EXPORT_C void DPrimaryMediaBase::NotifyMediaPresent() |
3715 /** |
3433 /** |
3716 Notifies clients of a media change by calling NotifyClients ( ) function to indicate that media is present. |
3434 Notifies clients of a media change by calling NotifyClients ( ) function to indicate that media is present. |
3717 */ |
3435 */ |
3718 { |
3436 { |
3719 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_ENTRY, this ); |
3437 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_ENTRY, this ); |
3720 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaPresent state %d",iMediaId,iState)); |
3438 NotifyClients(ETrue); |
3721 |
|
3722 // This should only be called in the context of the media thread |
|
3723 __ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT()); |
|
3724 |
|
3725 MediaChange(); |
|
3726 |
|
3727 NotifyClients(EMediaPresent); |
|
3728 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_EXIT, this ); |
3439 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_EXIT, this ); |
3729 } |
3440 } |
3730 |
3441 |
3731 EXPORT_C TInt DPrimaryMediaBase::DoInCritical() |
3442 EXPORT_C TInt DPrimaryMediaBase::DoInCritical() |
3732 /** |
3443 /** |
3873 if (r==KErrNone) |
3584 if (r==KErrNone) |
3874 { |
3585 { |
3875 TInt id=iMediaId; // start with primary media |
3586 TInt id=iMediaId; // start with primary media |
3876 TInt partitionsOnThisMedia=PartitionCount(); |
3587 TInt partitionsOnThisMedia=PartitionCount(); |
3877 TInt partition=0; |
3588 TInt partition=0; |
3878 |
3589 TInt j; |
3879 TDriveIterator driveIter; |
3590 for (j=0; j<KMaxLocalDrives; j++) |
3880 for (TLocDrv* pD = driveIter.NextDrive(); pD != NULL; pD = driveIter.NextDrive()) |
3591 { |
3881 { |
3592 TLocDrv* pD=TheDrives[j]; |
3882 if (pD && pD->iPrimaryMedia==this) |
3593 if (pD && pD->iPrimaryMedia==this) |
3883 { |
3594 { |
3884 if (totalPartitions==0) |
3595 if (totalPartitions==0) |
3885 { |
3596 { |
3886 pD->iMedia=NULL; |
3597 pD->iMedia=NULL; |
3913 // For data-paging media, calls DPagingDevice::NotifyBusy() when count goes positive |
3624 // For data-paging media, calls DPagingDevice::NotifyBusy() when count goes positive |
3914 // |
3625 // |
3915 void DPrimaryMediaBase::RequestCountInc() |
3626 void DPrimaryMediaBase::RequestCountInc() |
3916 { |
3627 { |
3917 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
3628 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
3918 if (iBody->iPagingDevice) |
3629 TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) 1); |
3919 { |
3630 //Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal); |
3920 NFastMutex* lock = iBody->iPagingDevice->NotificationLock(); |
3631 |
3921 NKern::FMWait(lock); |
3632 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal ); |
3922 TInt oldVal = iBody->iRequestCount++; |
3633 |
3923 //Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal); |
3634 if (oldVal == 0 && iBody->iPagingDevice) |
3924 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal ); |
3635 { |
3925 if (oldVal == 0) |
3636 //Kern::Printf("RCINC: NotifyBusy()"); |
3926 { |
3637 iBody->iPagingDevice->NotifyBusy(); |
3927 //Kern::Printf("RCINC: NotifyBusy()"); |
|
3928 iBody->iPagingDevice->NotifyBusy(); |
|
3929 } |
|
3930 NKern::FMSignal(lock); |
|
3931 } |
3638 } |
3932 } |
3639 } |
3933 |
3640 |
3934 // RequestCountDec() |
3641 // RequestCountDec() |
3935 // |
3642 // |
3937 // For data-paging media, calls DPagingDevice::NotifyIdle() when count reaches zero |
3644 // For data-paging media, calls DPagingDevice::NotifyIdle() when count reaches zero |
3938 // |
3645 // |
3939 void DPrimaryMediaBase::RequestCountDec() |
3646 void DPrimaryMediaBase::RequestCountDec() |
3940 { |
3647 { |
3941 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
3648 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
3942 if (iBody->iPagingDevice) |
3649 TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) -1); |
3943 { |
3650 //Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal); |
3944 NFastMutex* lock = iBody->iPagingDevice->NotificationLock(); |
3651 |
3945 NKern::FMWait(lock); |
3652 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal ); |
3946 TInt oldVal = iBody->iRequestCount--; |
3653 |
3947 //Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal); |
3654 if (oldVal == 1 && iBody->iPagingDevice) |
3948 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal ); |
3655 { |
3949 if (oldVal == 1) |
3656 //Kern::Printf("RCDEC: NotifyIdle()"); |
3950 { |
3657 iBody->iPagingDevice->NotifyIdle(); |
3951 //Kern::Printf("RCDEC: NotifyIdle()"); |
3658 } |
3952 iBody->iPagingDevice->NotifyIdle(); |
3659 __ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT()); |
3953 } |
|
3954 NKern::FMSignal(lock); |
|
3955 __ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT()); |
|
3956 } |
|
3957 } |
3660 } |
3958 #endif // __DEMAND_PAGING__ |
3661 #endif // __DEMAND_PAGING__ |
3959 |
3662 |
3960 TPartitionInfo::TPartitionInfo() |
3663 TPartitionInfo::TPartitionInfo() |
3961 // |
3664 // |
4252 // Read from the media and allow for retries in the unlikely event of an error. |
3955 // Read from the media and allow for retries in the unlikely event of an error. |
4253 const TInt KPageInRetries = 5; |
3956 const TInt KPageInRetries = 5; |
4254 TInt retVal = KErrGeneral; |
3957 TInt retVal = KErrGeneral; |
4255 for (TInt i=0; retVal != KErrNone && i < KPageInRetries; i++) |
3958 for (TInt i=0; retVal != KErrNone && i < KPageInRetries; i++) |
4256 { |
3959 { |
4257 m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging; |
3960 m.Flags() = TLocDrvRequest::EPaging; |
4258 TLocDrv* pL=NULL; |
3961 TLocDrv* pL=NULL; |
4259 if(aDrvNumber == EDriveRomPaging) // ROM paging |
3962 if(aDrvNumber == EDriveRomPaging) // ROM paging |
4260 { |
3963 { |
4261 m.Id() = DMediaPagingDevice::ERomPageInRequest; |
3964 m.Id() = DMediaPagingDevice::ERomPageInRequest; |
4262 if (iRomPagingDriveNumber == KErrNotFound) |
3965 if (iRomPagingDriveNumber == KErrNotFound) |
4291 else if ((aDrvNumber >=0) && (aDrvNumber<KMaxLocalDrives)) // Code paging |
3994 else if ((aDrvNumber >=0) && (aDrvNumber<KMaxLocalDrives)) // Code paging |
4292 { |
3995 { |
4293 m.Id() = DMediaPagingDevice::ECodePageInRequest; |
3996 m.Id() = DMediaPagingDevice::ECodePageInRequest; |
4294 m.Flags() |= TLocDrvRequest::ECodePaging; |
3997 m.Flags() |= TLocDrvRequest::ECodePaging; |
4295 pL=TheDrives[aDrvNumber]; |
3998 pL=TheDrives[aDrvNumber]; |
4296 __ASSERT_DEBUG(pL && TDriveIterator::GetDrive(aDrvNumber, iPrimaryMedia) ,LOCM_FAULT()); // valid drive number? |
3999 __ASSERT_DEBUG(pL&&(pL->iPrimaryMedia==iPrimaryMedia),LOCM_FAULT()); // valid drive number? |
4297 m.Drive()=pL; |
4000 m.Drive()=pL; |
4298 #ifdef __DEMAND_PAGING_BENCHMARKS__ |
4001 #ifdef __DEMAND_PAGING_BENCHMARKS__ |
4299 __e32_atomic_add_ord32(&iMediaPagingInfo.iCodePageInCount, (TUint) 1); |
4002 __e32_atomic_add_ord32(&iMediaPagingInfo.iCodePageInCount, (TUint) 1); |
4300 info = &iCodeBenchmarkData; |
4003 info = &iCodeBenchmarkData; |
4301 #endif |
4004 #endif |
4429 // Write to the media and allow for retries in the unlikely event of an error. |
4132 // Write to the media and allow for retries in the unlikely event of an error. |
4430 const TInt KPageOutRetries = 5; |
4133 const TInt KPageOutRetries = 5; |
4431 TInt retVal = KErrGeneral; |
4134 TInt retVal = KErrGeneral; |
4432 for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++) |
4135 for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++) |
4433 { |
4136 { |
4434 m.Flags() = TLocDrvRequest::EKernelBuffer | |
4137 m.Flags() = TLocDrvRequest::EPaging | |
4435 TLocDrvRequest::EPaging | |
|
4436 TLocDrvRequest::EDataPaging | |
4138 TLocDrvRequest::EDataPaging | |
4437 (aBackground ? TLocDrvRequest::EBackgroundPaging : 0) | |
4139 (aBackground ? TLocDrvRequest::EBackgroundPaging : 0) | |
4438 (aPhysAddr ? TLocDrvRequest::EPhysAddrOnly : 0); |
4140 (aPhysAddr ? TLocDrvRequest::EPhysAddrOnly : 0); |
4439 |
4141 |
4440 m.Id() = DLocalDrive::EWrite; |
4142 m.Id() = DLocalDrive::EWrite; |
4531 } |
4233 } |
4532 |
4234 |
4533 TLocDrvRequest& m=*(TLocDrvRequest*)(aReq); |
4235 TLocDrvRequest& m=*(TLocDrvRequest*)(aReq); |
4534 |
4236 |
4535 |
4237 |
4536 m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging; |
4238 m.Flags() = TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging; |
4537 m.Id() = DLocalDrive::EDeleteNotify; |
4239 m.Id() = DLocalDrive::EDeleteNotify; |
4538 m.Drive() = TheDrives[iDataPagingDriveNumber]; |
4240 m.Drive() = TheDrives[iDataPagingDriveNumber]; |
4539 |
4241 |
4540 m.RemoteThread() = NULL; |
4242 m.RemoteThread() = NULL; |
4541 m.Pos() = offset; |
4243 m.Pos() = offset; |
4564 OstTraceFunctionExitExt( DMEDIAPAGINGDEVICE_DELETENOTIFY_EXIT3, this, retVal ); |
4266 OstTraceFunctionExitExt( DMEDIAPAGINGDEVICE_DELETENOTIFY_EXIT3, this, retVal ); |
4565 return retVal; |
4267 return retVal; |
4566 } |
4268 } |
4567 |
4269 |
4568 |
4270 |
4271 |
|
4569 EXPORT_C TInt TLocDrvRequest::WriteToPageHandler(const TAny* aSrc, TInt aSize, TInt anOffset) |
4272 EXPORT_C TInt TLocDrvRequest::WriteToPageHandler(const TAny* aSrc, TInt aSize, TInt anOffset) |
4570 { |
4273 { |
4571 OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITETOPAGEHANDLER_ENTRY, this ); |
4274 OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITETOPAGEHANDLER_ENTRY, this ); |
4572 #ifdef BTRACE_PAGING_MEDIA |
4275 #ifdef BTRACE_PAGING_MEDIA |
4573 TMediaDevice medDev=Drive()->iMedia->iDevice; |
4276 TMediaDevice medDev=Drive()->iMedia->iDevice; |
4751 if (aLocDrv) |
4454 if (aLocDrv) |
4752 aLocDrv->iPartitionLen=aTotalSizeInBytes; |
4455 aLocDrv->iPartitionLen=aTotalSizeInBytes; |
4753 OstTraceFunctionExit1( DMEDIADRIVER_SETTOTALSIZEINBYTES_EXIT, this ); |
4456 OstTraceFunctionExit1( DMEDIADRIVER_SETTOTALSIZEINBYTES_EXIT, this ); |
4754 } |
4457 } |
4755 |
4458 |
4756 /** |
|
4757 For non NAND devices, i.e. devices which don't set TLocalDriveCapsV4::iNumOfBlocks, |
|
4758 set iSectorSizeInBytes, iNumberOfSectors & iNumPagesPerBlock appropriately to allow |
|
4759 TLocalDriveCapsV4::MediaSizeInBytes() to correctly return the media size |
|
4760 |
|
4761 Media drivers should call this when they receive a DLocalDrive::ECaps request |
|
4762 */ |
|
4763 EXPORT_C void DMediaDriver::SetTotalSizeInBytes(TLocalDriveCapsV4& aCaps) |
|
4764 { |
|
4765 if (aCaps.iNumOfBlocks == 0) |
|
4766 { |
|
4767 aCaps.iSectorSizeInBytes = 512; |
|
4768 aCaps.iNumPagesPerBlock = 1; // ...to ensure compatibility with NAND semantics |
|
4769 Int64 numberOfSectors = iTotalSizeInBytes >> 9; |
|
4770 while (I64HIGH(numberOfSectors) > 0) |
|
4771 { |
|
4772 aCaps.iNumPagesPerBlock<<= 1; |
|
4773 numberOfSectors>>= 1; |
|
4774 } |
|
4775 aCaps.iNumberOfSectors = I64LOW(numberOfSectors); |
|
4776 } |
|
4777 } |
|
4778 |
4459 |
4779 |
4460 |
4780 |
4461 |
4781 /** |
4462 /** |
4782 Gets the total size of the media. |
4463 Gets the total size of the media. |
5002 */ |
4683 */ |
5003 EXPORT_C TInt LocDrv::RegisterMediaDevice(TMediaDevice aDevice, TInt aDriveCount, const TInt* aDriveList, DPrimaryMediaBase* aPrimaryMedia, TInt aNumMedia, const TDesC& aName) |
4684 EXPORT_C TInt LocDrv::RegisterMediaDevice(TMediaDevice aDevice, TInt aDriveCount, const TInt* aDriveList, DPrimaryMediaBase* aPrimaryMedia, TInt aNumMedia, const TDesC& aName) |
5004 { |
4685 { |
5005 OstTraceFunctionEntry0( LOCDRV_REGISTERMEDIADEVICE_ENTRY ); |
4686 OstTraceFunctionEntry0( LOCDRV_REGISTERMEDIADEVICE_ENTRY ); |
5006 // Create TLocDrv / DMedia objects to handle a media device |
4687 // Create TLocDrv / DMedia objects to handle a media device |
5007 __KTRACE_OPT(KBOOT,Kern::Printf("RegisterMediaDevice %S dev=%1d #drives=%d 1st=%d PM=%08x #media=%d",&aName,aDevice,aDriveCount,*aDriveList,aPrimaryMedia,aNumMedia)); |
4688 __KTRACE_OPT(KBOOT,Kern::Printf("RegisterMediaDevice %lS dev=%1d #drives=%d 1st=%d PM=%08x #media=%d",&aName,aDevice,aDriveCount,*aDriveList,aPrimaryMedia,aNumMedia)); |
5008 OstTraceExt5( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE1, "aDevice=%d; aDriveCount=%d; aDriveList=%d; aPrimaryMedia=0x%08x; aNumMedia=%d", (TInt) aDevice, (TInt) aDriveCount, (TInt) *aDriveList, (TUint) aPrimaryMedia, (TInt) aNumMedia ); |
4689 OstTraceExt5( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE1, "aDevice=%d; aDriveCount=%d; aDriveList=%d; aPrimaryMedia=0x%08x; aNumMedia=%d", (TInt) aDevice, (TInt) aDriveCount, (TInt) *aDriveList, (TUint) aPrimaryMedia, (TInt) aNumMedia ); |
5009 |
4690 |
4691 const TInt* p=aDriveList; |
|
4692 TInt i; |
|
4693 TInt r=0; |
|
5010 if (UsedMedia+aNumMedia>KMaxLocalDrives) |
4694 if (UsedMedia+aNumMedia>KMaxLocalDrives) |
5011 { |
4695 { |
5012 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT1, "< KErrInUse"); |
4696 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT1, "< KErrInUse"); |
5013 return KErrInUse; |
4697 return KErrInUse; |
5014 } |
4698 } |
5015 |
4699 for (i=0; i<aDriveCount; ++i) |
5016 // make a local copy of the name |
4700 { |
4701 TInt drv = *p++; |
|
4702 // -1 means not used; this is to enable Dual-slot MMC support |
|
4703 if (drv == -1) |
|
4704 continue; |
|
4705 __KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv)); |
|
4706 OstTrace1( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE2, "Registering drive=%d", drv ); |
|
4707 if (TheDrives[drv]) |
|
4708 { |
|
4709 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv)); |
|
4710 OstTrace1( TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT2, "< Drive %d already in use; KErrInUse", drv); |
|
4711 return KErrInUse; |
|
4712 } |
|
4713 } |
|
5017 HBuf* pN=HBuf::New(aName); |
4714 HBuf* pN=HBuf::New(aName); |
5018 if (!pN) |
4715 if (!pN) |
5019 { |
4716 { |
5020 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT3, "< KErrNoMemory"); |
4717 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT3, "< KErrNoMemory"); |
5021 return KErrNoMemory; |
4718 return KErrNoMemory; |
5022 } |
4719 } |
5023 |
4720 TInt lastMedia=UsedMedia+aNumMedia-1; |
5024 // Register the primary media and any secondary media |
|
5025 TInt lastMedia = UsedMedia+aNumMedia-1; |
|
5026 TInt i; |
|
5027 TInt r=0; |
|
5028 for (i=UsedMedia; i<=lastMedia; ++i) |
4721 for (i=UsedMedia; i<=lastMedia; ++i) |
5029 { |
4722 { |
5030 if (i==UsedMedia) |
4723 if (i==UsedMedia) |
5031 TheMedia[i]=aPrimaryMedia; |
4724 TheMedia[i]=aPrimaryMedia; |
5032 else |
4725 else |
5043 { |
4736 { |
5044 OstTrace1(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT5, "< retval=%d", r); |
4737 OstTrace1(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT5, "< retval=%d", r); |
5045 return r; |
4738 return r; |
5046 } |
4739 } |
5047 } |
4740 } |
4741 |
|
5048 __KTRACE_OPT(KBOOT,Kern::Printf("FirstMedia %d LastMedia %d",UsedMedia,lastMedia)); |
4742 __KTRACE_OPT(KBOOT,Kern::Printf("FirstMedia %d LastMedia %d",UsedMedia,lastMedia)); |
5049 OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE4, "FirstMedia=%d; LastMedia=%d", UsedMedia, lastMedia ); |
4743 OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE4, "FirstMedia=%d; LastMedia=%d", UsedMedia, lastMedia ); |
5050 UsedMedia+=aNumMedia; |
4744 UsedMedia+=aNumMedia; |
5051 |
4745 p=aDriveList; |
5052 if (__IS_EXTENSION(aDevice)) |
|
5053 aPrimaryMedia->iBody->iMediaExtension = ETrue; |
|
5054 |
|
5055 // Register the drives |
|
5056 const TInt* p=aDriveList; |
|
5057 for (i=0; i<aDriveCount; ++i) |
4746 for (i=0; i<aDriveCount; ++i) |
5058 { |
4747 { |
5059 TInt drv = *p++; |
4748 TInt drv=*p++; |
5060 // -1 means not used; this is to enable Dual-slot MMC support |
|
5061 if (drv == -1) |
4749 if (drv == -1) |
5062 continue; |
4750 continue; |
5063 |
4751 TLocDrv* pL=new TLocDrv(drv); |
5064 __KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv)); |
4752 if (!pL) |
5065 if (!__IS_EXTENSION(aDevice) && TheDrives[drv]) |
4753 { |
5066 { |
|
5067 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv)); |
|
5068 return KErrInUse; |
|
5069 } |
|
5070 else if (__IS_EXTENSION(aDevice) && !TheDrives[drv]) |
|
5071 { |
|
5072 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d not initialized", drv)); |
|
5073 return KErrNotReady; |
|
5074 } |
|
5075 |
|
5076 TLocDrv* pNewDrive = new TLocDrv(drv); |
|
5077 if (!pNewDrive) |
|
5078 { |
|
5079 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT6, "< KErrNoMemory"); |
4754 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT6, "< KErrNoMemory"); |
5080 return KErrNoMemory; |
4755 return KErrNoMemory; |
5081 } |
4756 } |
5082 |
4757 TheDrives[drv]=pL; |
5083 |
4758 DriveNames[drv]=pN; |
5084 TLocDrv* pOldDrive = TheDrives[drv]; |
4759 pL->iPrimaryMedia=aPrimaryMedia; |
5085 aPrimaryMedia->iBody->iRegisteredDriveMask|= (0x1 << drv); |
4760 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pL)); |
5086 pNewDrive->iNextDrive = pOldDrive; |
4761 OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE5, "Drive=%d; TLocDrv 0x%08x;", (TInt) drv, (TUint) pL ); |
5087 |
4762 } |
5088 TheDrives[drv] = pNewDrive; |
|
5089 DriveNames[drv] = pN; |
|
5090 pNewDrive->iPrimaryMedia = aPrimaryMedia; |
|
5091 |
|
5092 |
|
5093 if (pOldDrive) |
|
5094 { |
|
5095 TInt r = pOldDrive->iPrimaryMedia->Connect(pNewDrive); |
|
5096 if (r != KErrNone) |
|
5097 return r; |
|
5098 |
|
5099 #ifdef __DEMAND_PAGING__ |
|
5100 // If we've hooked a drive letter which is being used for ROM paging by a media driver |
|
5101 // which does not report the ROM partition, then we need to change iFirstLocalDriveNumber |
|
5102 // so that ROM page-in requests go directly to that driver |
|
5103 DMediaPagingDevice* oldPagingDevice = pOldDrive->iPrimaryMedia->iBody->iPagingDevice; |
|
5104 if (oldPagingDevice && |
|
5105 (oldPagingDevice->iType & DPagingDevice::ERom) && |
|
5106 oldPagingDevice->iRomPagingDriveNumber == KErrNotFound && |
|
5107 oldPagingDevice->iFirstLocalDriveNumber == drv) |
|
5108 { |
|
5109 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: hooking ROM paging device with no defined ROM partition")); |
|
5110 TInt n; |
|
5111 for (n=0; n<KMaxLocalDrives; ++n) |
|
5112 { |
|
5113 if(TheDrives[n] && TheDrives[n]->iPrimaryMedia == pOldDrive->iPrimaryMedia) |
|
5114 { |
|
5115 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: Changing iFirstLocalDriveNumber from %d to %d", oldPagingDevice->iFirstLocalDriveNumber, n)); |
|
5116 oldPagingDevice->iFirstLocalDriveNumber = n; |
|
5117 break; |
|
5118 } |
|
5119 } |
|
5120 __ASSERT_ALWAYS(n < KMaxLocalDrives, LOCM_FAULT()); |
|
5121 } |
|
5122 #endif |
|
5123 |
|
5124 } |
|
5125 |
|
5126 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pNewDrive)); |
|
5127 } |
|
5128 |
|
5129 |
4763 |
5130 OstTraceFunctionExit0( LOCDRV_REGISTERMEDIADEVICE_EXIT7 ); |
4764 OstTraceFunctionExit0( LOCDRV_REGISTERMEDIADEVICE_EXIT7 ); |
5131 return KErrNone; |
4765 return KErrNone; |
5132 } |
4766 } |
5133 |
4767 |
5209 or one of the other system-wide error codes. |
4843 or one of the other system-wide error codes. |
5210 */ |
4844 */ |
5211 EXPORT_C TInt LocDrv::RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages) |
4845 EXPORT_C TInt LocDrv::RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages) |
5212 { |
4846 { |
5213 OstTraceFunctionEntry0( LOCDRV_REGISTERPAGINGDEVICE_ENTRY ); |
4847 OstTraceFunctionEntry0( LOCDRV_REGISTERPAGINGDEVICE_ENTRY ); |
5214 // SETDEBUGFLAG(KLOCDPAGING); |
|
5215 |
4848 |
5216 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf(">RegisterPagingDevice: paging type=%d PM=0x%x read shift=%d",aPagingType,aPrimaryMedia,aReadShift)); |
4849 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf(">RegisterPagingDevice: paging type=%d PM=0x%x read shift=%d",aPagingType,aPrimaryMedia,aReadShift)); |
5217 OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE1, "aPagingType=%d; aPrimaryMedia=0x%x; aReadShift=%d", (TInt) aPagingType, (TUint) aPrimaryMedia, (TInt) aReadShift); |
4850 OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE1, "aPagingType=%d; aPrimaryMedia=0x%x; aReadShift=%d", (TInt) aPagingType, (TUint) aPrimaryMedia, (TInt) aReadShift); |
5218 |
4851 |
5219 TInt i = 0; |
4852 TInt i; |
5220 |
4853 |
5221 if(!aPagingType || (aPagingType&~(DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData))) |
4854 if(!aPagingType || (aPagingType&~(DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData))) |
5222 { |
4855 { |
5223 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting")); |
4856 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting")); |
5224 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument"); |
4857 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument"); |
5225 return KErrArgument; |
4858 return KErrArgument; |
5226 } |
4859 } |
5227 |
4860 |
5228 |
4861 for(i=0; i<KMaxLocalDrives; i++) |
5229 // Check for duplicate drives |
4862 { |
5230 if (!aPrimaryMedia->iBody->iMediaExtension) |
4863 if (ThePagingDevices[i] == NULL) |
5231 { |
4864 continue; |
5232 for(i=0; i<KMaxLocalDrives; i++) |
4865 if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) && (aPagingType & DPagingDevice::ERom)) |
5233 { |
4866 { |
5234 if (ThePagingDevices[i] == NULL) |
4867 aPagingType&=~DPagingDevice::ERom; // already have a ROM paging device |
5235 continue; |
4868 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i)); |
5236 if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) && (aPagingType & DPagingDevice::ERom)) |
4869 } |
5237 { |
4870 if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData)) |
5238 aPagingType&=~DPagingDevice::ERom; // already have a ROM paging device |
4871 { |
5239 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i)); |
4872 aPagingType&=~DPagingDevice::EData; // already have a Data paging device |
5240 } |
4873 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i)); |
5241 if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData)) |
|
5242 { |
|
5243 aPagingType&=~DPagingDevice::EData; // already have a Data paging device |
|
5244 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i)); |
|
5245 } |
|
5246 } |
4874 } |
5247 } |
4875 } |
5248 |
4876 |
5249 |
4877 |
5250 if (aPagingType == 0) |
4878 if (aPagingType == 0) |
5323 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("DMediaPagingDevice(), firstLocalDriveNumber %d", firstLocalDriveNumber)); |
4951 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("DMediaPagingDevice(), firstLocalDriveNumber %d", firstLocalDriveNumber)); |
5324 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE3, "firstLocalDriveNumber=%d", firstLocalDriveNumber ); |
4952 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE3, "firstLocalDriveNumber=%d", firstLocalDriveNumber ); |
5325 |
4953 |
5326 // Send an ECaps message to wake up the media driver & ensure all partitions are |
4954 // Send an ECaps message to wake up the media driver & ensure all partitions are |
5327 // reported, then search for paged-data or paged-ROM partitions |
4955 // reported, then search for paged-data or paged-ROM partitions |
5328 // NB: older media drivers supporting ROM and/or code paging only may not have started their DFC queues, |
|
5329 // so for these media drivers, use the first local drive supported for ROM-pagin-in requests and |
|
5330 // assume the media driver itself will adjust the request position internally to match the ROM partition |
|
5331 // @see DMediaPagingDevice::Read() |
|
5332 if ((aPagingType & DPagingDevice::EData) || |
4956 if ((aPagingType & DPagingDevice::EData) || |
5333 (aPagingType & DPagingDevice::ERom && aPrimaryMedia->iDfcQ && aPrimaryMedia->iMsgQ.iReady)) |
4957 (aPagingType & DPagingDevice::ERom && aPrimaryMedia->iDfcQ && aPrimaryMedia->iMsgQ.iReady)) |
5334 { |
4958 { |
5335 // the message queue must have been started already (by the media driver calling iMsgQ.Receive()) |
4959 // the message queue must have been started already (by the media driver calling iMsgQ.Receive()) |
5336 // otherwise we can't send the DLocalDrive::ECaps request |
4960 // otherwise we can't send the DLocalDrive::EQueryDevice request |
5337 if (!aPrimaryMedia->iDfcQ || !aPrimaryMedia->iMsgQ.iReady) |
4961 if (aPrimaryMedia->iDfcQ && !aPrimaryMedia->iMsgQ.iReady) |
5338 { |
4962 { |
5339 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Message queue not started")); |
4963 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Message queue not started")); |
5340 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT8, "< RegisterPagingDevice: Message queue not started; KErrNotReady"); |
4964 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT8, "< RegisterPagingDevice: Message queue not started; KErrNotReady"); |
5341 return KErrNotReady; |
4965 return KErrNotReady; |
5342 } |
4966 } |
5367 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE4, "Paging device ECaps: i %d retval=%d", i, r); |
4991 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE4, "Paging device ECaps: i %d retval=%d", i, r); |
5368 } |
4992 } |
5369 |
4993 |
5370 if (r != KErrNone) |
4994 if (r != KErrNone) |
5371 { |
4995 { |
5372 OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< retval=%d",r); |
4996 OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< Caps::retval=%d - return KErrNotSupported",r); |
5373 // Media driver failure; media maybe recoverable after boot. |
4997 // Media driver failure; media maybe recoverable after boot. |
5374 // Can't register any page drives so return not supported. |
4998 // Can't register any page drives so return not supported. |
5375 return KErrNotSupported; |
4999 return KErrNotSupported; |
5376 } |
5000 } |
5377 |
5001 |
5382 for (i=0; i<KMaxLocalDrives; ++i) |
5006 for (i=0; i<KMaxLocalDrives; ++i) |
5383 { |
5007 { |
5384 drive = TheDrives[i]; |
5008 drive = TheDrives[i]; |
5385 if(drive && drive->iPrimaryMedia == aPrimaryMedia) |
5009 if(drive && drive->iPrimaryMedia == aPrimaryMedia) |
5386 { |
5010 { |
5387 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x base %lx size %lx name %S", i, drive->iPartitionType, drive->iPartitionBaseAddr, drive->iPartitionLen, DriveNames[i] ? DriveNames[i] : &KNullDesC8)); |
5011 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x size %x", i, drive->iPartitionType, I64LOW(drive->iPartitionLen))); |
5388 // ROM partition ? |
5012 // ROM partition ? |
5389 if ((romPagingDriveNumber == KErrNotFound) && |
5013 if ((romPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypeROM)) |
5390 (drive->iPartitionType == KPartitionTypeROM) && |
|
5391 (aPagingType & DPagingDevice::ERom)) |
|
5392 { |
5014 { |
5393 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found ROM partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
5015 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found ROM partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
5394 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE5, "Found ROM partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen)); |
5016 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE5, "Found ROM partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen)); |
5395 romPagingDriveNumber = i; |
5017 romPagingDriveNumber = i; |
5396 } |
5018 } |
5397 // swap partition ? |
5019 // swap partition ? |
5398 else if ((dataPagingDriveNumber == KErrNotFound) && |
5020 else if ((dataPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypePagedData)) |
5399 (drive->iPartitionType == KPartitionTypePagedData) && |
|
5400 (aPagingType & DPagingDevice::EData)) |
|
5401 { |
5021 { |
5402 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
5022 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
5403 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE6, "Found SWAP partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen) ); |
5023 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE6, "Found SWAP partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen) ); |
5404 dataPagingDriveNumber = i; |
5024 dataPagingDriveNumber = i; |
5405 TheDataPagingDrive = drive; |
|
5406 swapSize = drive->iPartitionLen >> aReadShift; |
5025 swapSize = drive->iPartitionLen >> aReadShift; |
5407 |
5026 |
5408 // Mark Paging Device capable of utilising physical addresss only accesses |
5027 // Mark Paging Device capable of utilising physical addresss only accesses |
5409 if (drive->iDmaHelper) |
5028 if (drive->iDmaHelper) |
5410 flags |= DPagingDevice::ESupportsPhysicalAccess; |
5029 flags |= DPagingDevice::ESupportsPhysicalAccess; |
5430 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory"); |
5049 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory"); |
5431 return KErrNoMemory; |
5050 return KErrNoMemory; |
5432 } |
5051 } |
5433 |
5052 |
5434 pagingDevice->iType = aPagingType; |
5053 pagingDevice->iType = aPagingType; |
5435 if (aPrimaryMedia->iBody->iMediaExtension) |
5054 pagingDevice->iFlags = flags; |
5436 pagingDevice->iType|= DPagingDevice::EMediaExtension; |
|
5437 |
|
5438 pagingDevice->iReadUnitShift = aReadShift; |
5055 pagingDevice->iReadUnitShift = aReadShift; |
5439 |
5056 |
5440 pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber; |
5057 pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber; |
5441 pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber; |
5058 pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber; |
5442 |
5059 |
5445 |
5062 |
5446 pagingDevice->iPreferredWriteShift = (blockSize) ? __e32_find_ms1_32(blockSize) : 0; |
5063 pagingDevice->iPreferredWriteShift = (blockSize) ? __e32_find_ms1_32(blockSize) : 0; |
5447 |
5064 |
5448 #ifdef __DEBUG_DEMAND_PAGING__ |
5065 #ifdef __DEBUG_DEMAND_PAGING__ |
5449 Kern::Printf("PagingDevice :"); |
5066 Kern::Printf("PagingDevice :"); |
5450 Kern::Printf("Name %S", firstLocalDriveNumber >= 0 && DriveNames[firstLocalDriveNumber] ? DriveNames[firstLocalDriveNumber] : &KNullDesC8); |
5067 Kern::Printf("iType 0x%x\n", pagingDevice->iType); |
5451 Kern::Printf("iType 0x%x", pagingDevice->iType); |
|
5452 Kern::Printf("iFlags 0x%x\n", pagingDevice->iFlags); |
5068 Kern::Printf("iFlags 0x%x\n", pagingDevice->iFlags); |
5453 Kern::Printf("iReadUnitShift 0x%x", pagingDevice->iReadUnitShift); |
5069 Kern::Printf("iReadUnitShift 0x%x\n", pagingDevice->iReadUnitShift); |
5454 Kern::Printf("iFirstLocalDriveNumber 0x%x", pagingDevice->iFirstLocalDriveNumber); |
5070 Kern::Printf("iFirstLocalDriveNumber 0x%x\n", pagingDevice->iFirstLocalDriveNumber); |
5455 Kern::Printf("iRomPagingDriveNumber 0x%x", pagingDevice->iRomPagingDriveNumber); |
5071 Kern::Printf("iRomPagingDriveNumber 0x%x\n", pagingDevice->iRomPagingDriveNumber); |
5456 Kern::Printf("iDataPagingDriveNumber 0x%x", pagingDevice->iDataPagingDriveNumber); |
5072 Kern::Printf("iDataPagingDriveNumber 0x%x\n", pagingDevice->iDataPagingDriveNumber); |
5457 Kern::Printf("iSwapSize 0x%x", pagingDevice->iSwapSize); |
5073 Kern::Printf("iSwapSize 0x%x\n", pagingDevice->iSwapSize); |
5458 Kern::Printf("iPreferredWriteShift 0x%x\n", pagingDevice->iPreferredWriteShift); |
5074 Kern::Printf("iPreferredWriteShift 0x%x\n", pagingDevice->iPreferredWriteShift); |
5459 #endif |
5075 #endif |
5460 |
5076 |
5461 |
5077 |
5462 // This table is indexed by DPagingDevice::TType |
5078 // This table is indexed by DPagingDevice::TType |
5474 |
5090 |
5475 |
5091 |
5476 if(aPagingType & DPagingDevice::ECode) |
5092 if(aPagingType & DPagingDevice::ECode) |
5477 { |
5093 { |
5478 for (i=0; i<aDriveCount; ++i) |
5094 for (i=0; i<aDriveCount; ++i) |
5479 pagingDevice->iDrivesSupported |= (0x1<<aPagingDriveList[i]); |
5095 pagingDevice->iDrivesSupported|=(0x1<<aPagingDriveList[i]); |
5480 } |
5096 } |
5481 pagingDevice->iName = DeviceName[aPagingType]; |
5097 pagingDevice->iName = DeviceName[aPagingType]; |
5482 |
5098 |
5483 // If ThePinObjectAllocator has already been created with a smaller number of pages, |
|
5484 // delete it & then re-create it |
|
5485 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: ThePinObjectAllocator %x", ThePinObjectAllocator)); |
|
5486 if (ThePinObjectAllocator && ThePinObjectAllocator->iFragmentGranularity < Kern::RoundToPageSize(1) * aNumPages) |
|
5487 { |
|
5488 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Recreating ThePinObjectAllocator...")); |
|
5489 delete ThePinObjectAllocator; |
|
5490 ThePinObjectAllocator = NULL; |
|
5491 } |
|
5492 |
|
5493 |
|
5494 TInt r; |
|
5495 if (ThePinObjectAllocator == NULL) |
5099 if (ThePinObjectAllocator == NULL) |
5496 { |
|
5497 ThePinObjectAllocator = new DPinObjectAllocator(); |
5100 ThePinObjectAllocator = new DPinObjectAllocator(); |
5498 if(!ThePinObjectAllocator) |
5101 if(!ThePinObjectAllocator) |
5499 { |
5102 { |
5500 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator")); |
5103 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator")); |
5501 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory"); |
5104 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory"); |
5502 return KErrNoMemory; |
5105 return KErrNoMemory; |
5503 } |
5106 } |
5504 r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages); |
5107 TInt r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages); |
5505 if (r != KErrNone) |
5108 if (r != KErrNone) |
5506 { |
5109 { |
5507 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator")); |
5110 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator")); |
5508 OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r); |
5111 OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r); |
5509 return r; |
5112 return r; |
5510 } |
|
5511 } |
5113 } |
5512 |
5114 |
5513 |
5115 |
5514 // Register our DPagingDevice with the Kernel |
5116 // Register our DPagingDevice with the Kernel |
5515 r=Kern::InstallPagingDevice(pagingDevice); |
5117 r=Kern::InstallPagingDevice(pagingDevice); |
5535 if (aPagingType&DPagingDevice::ECode) |
5137 if (aPagingType&DPagingDevice::ECode) |
5536 { |
5138 { |
5537 for (i=0; i<aDriveCount; ++i) |
5139 for (i=0; i<aDriveCount; ++i) |
5538 { |
5140 { |
5539 TLocDrv* pD=TheDrives[*p++]; |
5141 TLocDrv* pD=TheDrives[*p++]; |
5540 pD->iPagingDrv = 1; |
5142 pD->iPagingDrv=1; |
5541 // mark all attached drives as pageable too - this is really |
|
5542 // only to avoid hitting an ASSERT in DMediaDriver::Complete() |
|
5543 while (pD->iNextDrive) |
|
5544 { |
|
5545 pD->iNextDrive->iPagingDrv = 1; |
|
5546 pD = pD->iNextDrive; |
|
5547 } |
|
5548 } |
5143 } |
5549 } |
5144 } |
5550 |
5145 |
5551 // Flags to indicate that a paging device is registered and pinning of user requests may be required |
5146 // Flags to indicate that a paging device is registered and pinning of user requests may be required |
5552 aPrimaryMedia->iPagingMedia = 1; |
5147 aPrimaryMedia->iPagingMedia = 1; |
5586 TheDataPagingMedia = aPrimaryMedia; |
5181 TheDataPagingMedia = aPrimaryMedia; |
5587 } |
5182 } |
5588 |
5183 |
5589 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("< RegisterPagingDevice")); |
5184 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("< RegisterPagingDevice")); |
5590 OstTraceFunctionExit0( LOCDRV_REGISTERPAGINGDEVICE_EXIT14 ); |
5185 OstTraceFunctionExit0( LOCDRV_REGISTERPAGINGDEVICE_EXIT14 ); |
5591 // CLRDEBUGFLAG(KLOCDPAGING); |
|
5592 return KErrNone; |
5186 return KErrNone; |
5593 } |
5187 } |
5594 |
5188 |
5595 #else //__DEMAND_PAGING__ |
5189 #else //__DEMAND_PAGING__ |
5596 |
5190 |
5662 for (i=0; i<KMaxLocalDrives; ++i) |
5256 for (i=0; i<KMaxLocalDrives; ++i) |
5663 { |
5257 { |
5664 TLocDrv* pL=TheDrives[i]; |
5258 TLocDrv* pL=TheDrives[i]; |
5665 if (pL) |
5259 if (pL) |
5666 { |
5260 { |
5667 pL = TDriveIterator::GetPhysicalDrive(TheDrives[i]); |
|
5668 ++drives; |
5261 ++drives; |
5669 TInt sockNum; |
5262 TInt sockNum; |
5670 DPrimaryMediaBase* pM=pL->iPrimaryMedia; |
5263 DPrimaryMediaBase* pM=pL->iPrimaryMedia; |
5671 if (pM->IsRemovableDevice(sockNum)) |
5264 if (pM->IsRemovableDevice(sockNum)) |
5672 { |
5265 { |
5673 if (!(sock_mask & (1<<sockNum))) |
5266 if (!(sock_mask & (1<<sockNum))) |
5674 { |
5267 { |
5675 info.iSocketName[sockNum]=*DriveNames[i]; |
5268 info.iSocketName[sockNum]=*DriveNames[i]; |
5676 __KTRACE_OPT(KLOCDRV,Kern::Printf("Socket %d device %d name %S", sockNum, pM->iDevice, DriveNames[i])); |
5269 __KTRACE_OPT(KLOCDRV,Kern::Printf("Socket %d device %d name %lS", sockNum, pM->iDevice, DriveNames[i])); |
5677 OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO1, "Socket=%d; device=%d", sockNum, (TUint) pM->iDevice ); |
5270 OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO1, "Socket=%d; device=%d", sockNum, (TUint) pM->iDevice ); |
5678 if ( (sockNum + 1) > sockets ) |
5271 if ( (sockNum + 1) > sockets ) |
5679 sockets = sockNum + 1; |
5272 sockets = sockNum + 1; |
5680 } |
5273 } |
5681 sock_mask |= (1<<sockNum); |
5274 sock_mask |= (1<<sockNum); |
5682 } |
5275 } |
5683 info.iDriveName[i]=*DriveNames[i]; |
5276 info.iDriveName[i]=*DriveNames[i]; |
5684 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d device %d name %S",i,pM->iDevice,DriveNames[i])); |
5277 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d device %d name %lS",i,pM->iDevice,DriveNames[i])); |
5685 OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO2, "Drive=%d; device=%d", i, (TUint) pM->iDevice ); |
5278 OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO2, "Drive=%d; device=%d", i, (TUint) pM->iDevice ); |
5686 |
5279 |
5687 info.iRegisteredDriveBitmask |= (0x01 << i); |
5280 info.iRegisteredDriveBitmask |= (0x01 << i); |
5688 } |
5281 } |
5689 } |
5282 } |
5802 break; |
5395 break; |
5803 } |
5396 } |
5804 #if defined(__DEMAND_PAGING__) && defined(__CONCURRENT_PAGING_INSTRUMENTATION__) |
5397 #if defined(__DEMAND_PAGING__) && defined(__CONCURRENT_PAGING_INSTRUMENTATION__) |
5805 case EMediaHalGetROMConcurrencyInfo: |
5398 case EMediaHalGetROMConcurrencyInfo: |
5806 { |
5399 { |
5807 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom); |
5400 TInt drvNo=(TInt)a1; |
5401 TLocDrv* drv=TheDrives[drvNo]; |
|
5402 if(!drv) |
|
5403 break; |
|
5404 DMediaPagingDevice* device = drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5808 if(!device) |
5405 if(!device) |
5809 break; |
5406 break; |
5810 NKern::FMWait(&device->iInstrumentationLock); |
5407 NKern::FMWait(&device->iInstrumentationLock); |
5811 SMediaROMPagingConcurrencyInfo info=device->iROMStats; |
5408 SMediaROMPagingConcurrencyInfo info=device->iROMStats; |
5812 NKern::FMSignal(&device->iInstrumentationLock); |
5409 NKern::FMSignal(&device->iInstrumentationLock); |
5814 r=KErrNone; |
5411 r=KErrNone; |
5815 break; |
5412 break; |
5816 } |
5413 } |
5817 case EMediaHalGetCodeConcurrencyInfo: |
5414 case EMediaHalGetCodeConcurrencyInfo: |
5818 { |
5415 { |
5819 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode); |
5416 TInt drvNo=(TInt)a1; |
5417 TLocDrv* drv=TheDrives[drvNo]; |
|
5418 if(!drv) |
|
5419 break; |
|
5420 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5820 if(!device) |
5421 if(!device) |
5821 break; |
5422 break; |
5822 NKern::FMWait(&device->iInstrumentationLock); |
5423 NKern::FMWait(&device->iInstrumentationLock); |
5823 SMediaCodePagingConcurrencyInfo info=device->iCodeStats; |
5424 SMediaCodePagingConcurrencyInfo info=device->iCodeStats; |
5824 NKern::FMSignal(&device->iInstrumentationLock); |
5425 NKern::FMSignal(&device->iInstrumentationLock); |
5826 r=KErrNone; |
5427 r=KErrNone; |
5827 break; |
5428 break; |
5828 } |
5429 } |
5829 case EMediaHalGetDataConcurrencyInfo: |
5430 case EMediaHalGetDataConcurrencyInfo: |
5830 { |
5431 { |
5831 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData); |
5432 TInt drvNo=(TInt)a1; |
5433 TLocDrv* drv=TheDrives[drvNo]; |
|
5434 if(!drv) |
|
5435 break; |
|
5436 DMediaPagingDevice* device = drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5832 if(!device) |
5437 if(!device) |
5833 break; |
5438 break; |
5834 NKern::FMWait(&device->iInstrumentationLock); |
5439 NKern::FMWait(&device->iInstrumentationLock); |
5835 SMediaDataPagingConcurrencyInfo info=device->iDataStats; |
5440 SMediaDataPagingConcurrencyInfo info=device->iDataStats; |
5836 NKern::FMSignal(&device->iInstrumentationLock); |
5441 NKern::FMSignal(&device->iInstrumentationLock); |
5838 r=KErrNone; |
5443 r=KErrNone; |
5839 break; |
5444 break; |
5840 } |
5445 } |
5841 case EMediaHalResetConcurrencyInfo: |
5446 case EMediaHalResetConcurrencyInfo: |
5842 { |
5447 { |
5448 TInt drvNo=(TInt)a1; |
|
5449 TLocDrv* drv=TheDrives[drvNo]; |
|
5450 if(!drv) |
|
5451 break; |
|
5452 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5453 if(!device) |
|
5454 break; |
|
5843 TUint index=(TInt)a2; |
5455 TUint index=(TInt)a2; |
5844 if(index>EMediaPagingStatsCode) |
5456 if(index>EMediaPagingStatsCode) |
5845 break; |
5457 break; |
5846 |
5458 ResetConcurrencyStats(device, (TMediaPagingStats)index); |
5847 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom); |
|
5848 if (device) |
|
5849 ResetConcurrencyStats(device, (TMediaPagingStats)index); |
|
5850 device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode); |
|
5851 if (device) |
|
5852 ResetConcurrencyStats(device, (TMediaPagingStats)index); |
|
5853 device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData); |
|
5854 if (device) |
|
5855 ResetConcurrencyStats(device, (TMediaPagingStats)index); |
|
5856 |
|
5857 r=KErrNone; |
5459 r=KErrNone; |
5858 break; |
5460 break; |
5859 } |
5461 } |
5860 #endif |
5462 #endif |
5861 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__) |
5463 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__) |
5862 case EMediaHalGetROMPagingBenchmark: |
5464 case EMediaHalGetROMPagingBenchmark: |
5863 { |
5465 { |
5864 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom); |
5466 TInt drvNo=(TInt)a1; |
5467 TLocDrv* drv=TheDrives[drvNo]; |
|
5468 if(!drv) |
|
5469 break; |
|
5470 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5865 if(!device) |
5471 if(!device) |
5866 break; |
5472 break; |
5867 NKern::FMWait(&device->iInstrumentationLock); |
5473 NKern::FMWait(&device->iInstrumentationLock); |
5868 SPagingBenchmarkInfo info = device->iROMBenchmarkData; |
5474 SPagingBenchmarkInfo info = device->iROMBenchmarkData; |
5869 NKern::FMSignal(&device->iInstrumentationLock); |
5475 NKern::FMSignal(&device->iInstrumentationLock); |
5871 r=KErrNone; |
5477 r=KErrNone; |
5872 break; |
5478 break; |
5873 } |
5479 } |
5874 case EMediaHalGetCodePagingBenchmark: |
5480 case EMediaHalGetCodePagingBenchmark: |
5875 { |
5481 { |
5876 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode); |
5482 TInt drvNo=(TInt)a1; |
5483 TLocDrv* drv=TheDrives[drvNo]; |
|
5484 if(!drv) |
|
5485 break; |
|
5486 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5877 if(!device) |
5487 if(!device) |
5878 break; |
5488 break; |
5879 NKern::FMWait(&device->iInstrumentationLock); |
5489 NKern::FMWait(&device->iInstrumentationLock); |
5880 SPagingBenchmarkInfo info = device->iCodeBenchmarkData; |
5490 SPagingBenchmarkInfo info = device->iCodeBenchmarkData; |
5881 NKern::FMSignal(&device->iInstrumentationLock); |
5491 NKern::FMSignal(&device->iInstrumentationLock); |
5883 r=KErrNone; |
5493 r=KErrNone; |
5884 break; |
5494 break; |
5885 } |
5495 } |
5886 case EMediaHalGetDataInPagingBenchmark: |
5496 case EMediaHalGetDataInPagingBenchmark: |
5887 { |
5497 { |
5888 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData); |
5498 TInt drvNo=(TInt)a1; |
5499 TLocDrv* drv=TheDrives[drvNo]; |
|
5500 if(!drv) |
|
5501 break; |
|
5502 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5889 if(!device) |
5503 if(!device) |
5890 break; |
5504 break; |
5891 NKern::FMWait(&device->iInstrumentationLock); |
5505 NKern::FMWait(&device->iInstrumentationLock); |
5892 SPagingBenchmarkInfo info = device->iDataInBenchmarkData; |
5506 SPagingBenchmarkInfo info = device->iDataInBenchmarkData; |
5893 NKern::FMSignal(&device->iInstrumentationLock); |
5507 NKern::FMSignal(&device->iInstrumentationLock); |
5895 r=KErrNone; |
5509 r=KErrNone; |
5896 break; |
5510 break; |
5897 } |
5511 } |
5898 case EMediaHalGetDataOutPagingBenchmark: |
5512 case EMediaHalGetDataOutPagingBenchmark: |
5899 { |
5513 { |
5900 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData); |
5514 TInt drvNo=(TInt)a1; |
5515 TLocDrv* drv=TheDrives[drvNo]; |
|
5516 if(!drv) |
|
5517 break; |
|
5518 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5901 if(!device) |
5519 if(!device) |
5902 break; |
5520 break; |
5903 NKern::FMWait(&device->iInstrumentationLock); |
5521 NKern::FMWait(&device->iInstrumentationLock); |
5904 SPagingBenchmarkInfo info = device->iDataOutBenchmarkData; |
5522 SPagingBenchmarkInfo info = device->iDataOutBenchmarkData; |
5905 NKern::FMSignal(&device->iInstrumentationLock); |
5523 NKern::FMSignal(&device->iInstrumentationLock); |
5907 r=KErrNone; |
5525 r=KErrNone; |
5908 break; |
5526 break; |
5909 } |
5527 } |
5910 case EMediaHalResetPagingBenchmark: |
5528 case EMediaHalResetPagingBenchmark: |
5911 { |
5529 { |
5530 TInt drvNo=(TInt)a1; |
|
5531 TLocDrv* drv=TheDrives[drvNo]; |
|
5532 if(!drv) |
|
5533 break; |
|
5534 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5535 if(!device) |
|
5536 break; |
|
5912 TUint index=(TInt)a2; |
5537 TUint index=(TInt)a2; |
5913 if(index>EMediaPagingStatsCode) |
5538 if(index>EMediaPagingStatsCode) |
5914 break; |
5539 break; |
5915 |
5540 ResetBenchmarkStats(device, (TMediaPagingStats)index); |
5916 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom); |
|
5917 if (device) |
|
5918 ResetBenchmarkStats(device, (TMediaPagingStats)index); |
|
5919 device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode); |
|
5920 if (device) |
|
5921 ResetBenchmarkStats(device, (TMediaPagingStats)index); |
|
5922 device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData); |
|
5923 if (device) |
|
5924 ResetBenchmarkStats(device, (TMediaPagingStats)index); |
|
5925 |
|
5926 r=KErrNone; |
5541 r=KErrNone; |
5927 break; |
5542 break; |
5928 } |
5543 } |
5929 case EMediaHalGetPagingInfo: |
5544 case EMediaHalGetPagingInfo: |
5930 { |
5545 { |
5931 DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, (DPagingDevice::TType) 0xFF); |
5546 TInt drvNo=(TInt)a1; |
5547 TLocDrv* drv=TheDrives[drvNo]; |
|
5548 if(!drv) |
|
5549 break; |
|
5550 DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice; |
|
5932 if(!device) |
5551 if(!device) |
5933 break; |
5552 break; |
5934 NKern::FMWait(&device->iInstrumentationLock); |
5553 NKern::FMWait(&device->iInstrumentationLock); |
5935 SMediaPagingInfo info = device->iMediaPagingInfo; |
5554 SMediaPagingInfo info = device->iMediaPagingInfo; |
5936 NKern::FMSignal(&device->iInstrumentationLock); |
5555 NKern::FMSignal(&device->iInstrumentationLock); |
6166 } |
5785 } |
6167 } |
5786 } |
6168 |
5787 |
6169 |
5788 |
6170 /****************************************************************************** |
5789 /****************************************************************************** |
6171 DMediaDriverExtension base class |
|
6172 ******************************************************************************/ |
|
6173 |
|
6174 EXPORT_C DMediaDriverExtension::DMediaDriverExtension(TInt aMediaId) : |
|
6175 DMediaDriver(aMediaId) |
|
6176 { |
|
6177 } |
|
6178 |
|
6179 /** |
|
6180 */ |
|
6181 EXPORT_C DMediaDriverExtension::~DMediaDriverExtension() |
|
6182 { |
|
6183 } |
|
6184 |
|
6185 /** |
|
6186 Closes the media driver. |
|
6187 |
|
6188 This default implementation simply deletes this DMediaDriverExtension object. |
|
6189 |
|
6190 Media drivers can provide their own implementation, which gives them |
|
6191 the opportunity to clean up resources before closure; for example, |
|
6192 cancelling a DFC. |
|
6193 Any replacement function must call this base class function as |
|
6194 the last instruction. |
|
6195 */ |
|
6196 EXPORT_C void DMediaDriverExtension::Close() |
|
6197 { |
|
6198 DMediaDriver::Close(); |
|
6199 } |
|
6200 |
|
6201 /** |
|
6202 DoDrivePartitionInfo() |
|
6203 |
|
6204 Fills out the passed TPartitionInfo object with information from the attached drives |
|
6205 */ |
|
6206 EXPORT_C TInt DMediaDriverExtension::DoDrivePartitionInfo(TPartitionInfo& aInfo) |
|
6207 { |
|
6208 memclr(&aInfo, sizeof(aInfo)); |
|
6209 aInfo.iPartitionCount = 0; |
|
6210 aInfo.iMediaSizeInBytes = 0; |
|
6211 |
|
6212 TDriveIterator driveIter; |
|
6213 for (TLocDrv* drv = driveIter.NextDrive(); drv != NULL; drv = driveIter.NextDrive()) |
|
6214 { |
|
6215 if (drv && drv->iPrimaryMedia == iPrimaryMedia) |
|
6216 { |
|
6217 TLocDrv* attachedDrive = drv->iNextDrive; |
|
6218 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6219 TLocDrvRequest m; |
|
6220 memclr(&m, sizeof(m)); |
|
6221 |
|
6222 // Get the Caps from the device. NB for MMC/SD we may need to retry as there may have been an earlier |
|
6223 // EForceMediaChange request which can result in the cancellation of requests already in the queue |
|
6224 TBuf8<KMaxLocalDriveCapsLength> capsBuf; |
|
6225 TInt i; |
|
6226 const TInt KRetries = 5; |
|
6227 TInt r = KErrNotReady; |
|
6228 for (i=0; r == KErrNotReady && i < KRetries; i++) |
|
6229 { |
|
6230 capsBuf.SetMax(); |
|
6231 capsBuf.FillZ(); |
|
6232 m.Drive() = attachedDrive; |
|
6233 m.Id() = DLocalDrive::ECaps; |
|
6234 m.RemoteDes() = (TAny*)capsBuf.Ptr(); |
|
6235 m.Length() = KMaxLocalDriveCapsLength; |
|
6236 r = attachedDrive->iPrimaryMedia->Request(m); |
|
6237 } |
|
6238 |
|
6239 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("DMediaDriverExtension::PartitionInfo(ECaps: i %d: r %d ", driveIter.Index(), r)); |
|
6240 |
|
6241 // NB The ECaps call might legitimately fail if one of the attached drives is removable |
|
6242 // If this happens, just ignore & proceed to the next attached drive |
|
6243 if (r == KErrNone) |
|
6244 { |
|
6245 aInfo.iEntry[aInfo.iPartitionCount] = *attachedDrive; |
|
6246 // Set the media size to be that of the largest attached media |
|
6247 // This is only needed to ensure that the test in TLocDrvRequest::CheckAndAdjustForPartition() |
|
6248 // with the ELocDrvWholeMedia flag set succeeds: A further check on whether a request's |
|
6249 // position & length are outside the media will be made when its is delievered to the attached media.... |
|
6250 aInfo.iMediaSizeInBytes = Max( |
|
6251 aInfo.iMediaSizeInBytes, |
|
6252 ((TLocalDriveCapsV4*) capsBuf.Ptr())->MediaSizeInBytes()); |
|
6253 } |
|
6254 |
|
6255 |
|
6256 aInfo.iPartitionCount++; |
|
6257 } |
|
6258 } |
|
6259 |
|
6260 return KErrNone; |
|
6261 } |
|
6262 |
|
6263 /** |
|
6264 ForwardRequest() - |
|
6265 |
|
6266 forwards the request onto the next attached drive in the chain |
|
6267 */ |
|
6268 EXPORT_C TInt DMediaDriverExtension::ForwardRequest(TLocDrvRequest& aRequest) |
|
6269 { |
|
6270 TLocDrv* drive = aRequest.Drive(); |
|
6271 TLocDrv* attachedDrive = drive->iNextDrive; |
|
6272 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6273 aRequest.Drive() = attachedDrive; |
|
6274 |
|
6275 |
|
6276 TInt r = attachedDrive->iPrimaryMedia->HandleMediaNotPresent(aRequest); |
|
6277 if (r != KErrNone) |
|
6278 { |
|
6279 return r; |
|
6280 } |
|
6281 |
|
6282 aRequest.Forward(&attachedDrive->iPrimaryMedia->iMsgQ, EFalse); |
|
6283 return KErrNone; |
|
6284 } |
|
6285 |
|
6286 |
|
6287 TInt DMediaDriverExtension::SendRequest(TInt aReqId, TBool aPagingRequest, TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6288 { |
|
6289 __ASSERT_DEBUG(aLen > 0, LOCM_FAULT()); |
|
6290 |
|
6291 // Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice() |
|
6292 if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber))) |
|
6293 return KErrArgument; |
|
6294 |
|
6295 TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia); |
|
6296 __ASSERT_DEBUG(drive, LOCM_FAULT()); |
|
6297 TLocDrv* attachedDrive = drive->iNextDrive; |
|
6298 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6299 |
|
6300 TLocDrvRequest request; |
|
6301 memclr(&request, sizeof(request)); |
|
6302 |
|
6303 request.Drive() = attachedDrive; |
|
6304 request.Id() = aReqId; |
|
6305 request.Length() = aLen; |
|
6306 request.RemoteDes() = (TAny*) aData; |
|
6307 request.Pos() = aPos; |
|
6308 request.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EAdjusted; |
|
6309 |
|
6310 #ifdef __DEMAND_PAGING__ |
|
6311 if (aPagingRequest) |
|
6312 { |
|
6313 request.Flags()|= TLocDrvRequest::EPaging; |
|
6314 // If the buffer is page aligned, use SendToMainQueueDfcAndBlock() as this |
|
6315 // is more efficient if the attached drive use DMA. |
|
6316 const TInt KPageSizeMask = 4096-1; |
|
6317 if (aData & KPageSizeMask) |
|
6318 { |
|
6319 return attachedDrive->iPrimaryMedia->SendReceive(request, aData); |
|
6320 } |
|
6321 else |
|
6322 { |
|
6323 attachedDrive->iPrimaryMedia->iBody->iPagingDevice->SendToMainQueueDfcAndBlock(&request); |
|
6324 return 0; |
|
6325 } |
|
6326 } |
|
6327 #else |
|
6328 aPagingRequest; |
|
6329 #endif |
|
6330 |
|
6331 return attachedDrive->iPrimaryMedia->SendReceive(request, aData); |
|
6332 } |
|
6333 |
|
6334 |
|
6335 /** |
|
6336 Read() - |
|
6337 |
|
6338 reads data from the next attached drive in the chain |
|
6339 |
|
6340 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6341 media, not the partition |
|
6342 */ |
|
6343 EXPORT_C TInt DMediaDriverExtension::Read(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6344 { |
|
6345 return SendRequest(DLocalDrive::ERead, EFalse, aDriveNumber, aPos, aData, aLen); |
|
6346 } |
|
6347 |
|
6348 /** |
|
6349 Write() - |
|
6350 |
|
6351 writes data to the next attached drive in the chain |
|
6352 |
|
6353 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6354 media, not the partition |
|
6355 */ |
|
6356 EXPORT_C TInt DMediaDriverExtension::Write(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6357 { |
|
6358 return SendRequest(DLocalDrive::EWrite, EFalse, aDriveNumber, aPos, aData, aLen); |
|
6359 } |
|
6360 |
|
6361 |
|
6362 #ifdef __DEMAND_PAGING__ |
|
6363 /** |
|
6364 ReadPaged() - |
|
6365 |
|
6366 Sends a paging read request to the specified attached drive |
|
6367 |
|
6368 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6369 media, not the partition |
|
6370 */ |
|
6371 EXPORT_C TInt DMediaDriverExtension::ReadPaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6372 { |
|
6373 return SendRequest(DLocalDrive::ERead, ETrue, aDriveNumber, aPos, aData, aLen); |
|
6374 } |
|
6375 |
|
6376 /** |
|
6377 WritePaged() - |
|
6378 |
|
6379 Send a paging write request to the specified attached drive |
|
6380 |
|
6381 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6382 media, not the partition |
|
6383 */ |
|
6384 EXPORT_C TInt DMediaDriverExtension::WritePaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6385 { |
|
6386 return SendRequest(DLocalDrive::EWrite, ETrue, aDriveNumber, aPos, aData, aLen); |
|
6387 } |
|
6388 #endif // __DEMAND_PAGING__ |
|
6389 |
|
6390 |
|
6391 |
|
6392 /** |
|
6393 Caps() - |
|
6394 |
|
6395 gets the caps from the next attached drive in the chain |
|
6396 |
|
6397 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6398 media, not the partition |
|
6399 */ |
|
6400 EXPORT_C TInt DMediaDriverExtension::Caps(TInt aDriveNumber, TDes8& aCaps) |
|
6401 { |
|
6402 // Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice() |
|
6403 if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber))) |
|
6404 return KErrArgument; |
|
6405 |
|
6406 TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia); |
|
6407 __ASSERT_DEBUG(drive, LOCM_FAULT()); |
|
6408 TLocDrv* attachedDrive = drive->iNextDrive; |
|
6409 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6410 |
|
6411 TLocDrvRequest request; |
|
6412 memclr(&request, sizeof(request)); |
|
6413 |
|
6414 request.Drive() = attachedDrive; |
|
6415 request.Id() = DLocalDrive::ECaps; |
|
6416 request.Length() = aCaps.Length(); |
|
6417 request.RemoteDes() = (TAny*) aCaps.Ptr(); |
|
6418 |
|
6419 return request.SendReceive(&attachedDrive->iPrimaryMedia->iMsgQ); |
|
6420 } |
|
6421 |
|
6422 |
|
6423 |
|
6424 EXPORT_C void DMediaDriverExtension::NotifyPowerDown() |
|
6425 { |
|
6426 } |
|
6427 |
|
6428 EXPORT_C void DMediaDriverExtension::NotifyEmergencyPowerDown() |
|
6429 { |
|
6430 } |
|
6431 |
|
6432 |
|
6433 /** |
|
6434 Returns ETrue if this media - or any media which this TLocDrv is attached to - is busy |
|
6435 */ |
|
6436 EXPORT_C TBool DMediaDriverExtension::MediaBusy(TInt aDriveNumber) |
|
6437 { |
|
6438 for (TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia); |
|
6439 drive; |
|
6440 drive = drive->iNextDrive) |
|
6441 { |
|
6442 DPrimaryMediaBase* primaryMedia = drive->iPrimaryMedia; |
|
6443 __ASSERT_DEBUG(primaryMedia, LOCM_FAULT()); |
|
6444 |
|
6445 if ((primaryMedia->iMsgQ.iMessage && primaryMedia->iMsgQ.iMessage->iState != TMessageBase::EFree) || |
|
6446 !primaryMedia->iMsgQ.iQ.IsEmpty() || |
|
6447 primaryMedia->iBody->iMediaChangeDfc.Queued() || |
|
6448 primaryMedia->iBody->iMediaPresentDfc.Queued()) |
|
6449 return ETrue; |
|
6450 |
|
6451 #ifdef __DEMAND_PAGING__ |
|
6452 DMediaPagingDevice* pagingDevice = iPrimaryMedia->iBody->iPagingDevice; |
|
6453 if (pagingDevice) |
|
6454 { |
|
6455 if ((pagingDevice->iMainQ.iMessage && pagingDevice->iMainQ.iMessage->iState != TMessageBase::EFree) || |
|
6456 !pagingDevice->iMainQ.iQ.IsEmpty()) |
|
6457 return ETrue; |
|
6458 } |
|
6459 #endif |
|
6460 } |
|
6461 |
|
6462 return EFalse; |
|
6463 } |
|
6464 |
|
6465 |
|
6466 TCallBackLink::TCallBackLink() |
|
6467 { |
|
6468 memclr(this, sizeof(this)); |
|
6469 } |
|
6470 |
|
6471 TCallBackLink::TCallBackLink(TInt (*aFunction)(TAny* aPtr, TInt aParam),TAny* aPtr, TObjectType aObjectType) : |
|
6472 iFunction(aFunction), iPtr(aPtr), iObjectType(aObjectType) |
|
6473 { |
|
6474 } |
|
6475 |
|
6476 TInt TCallBackLink::CallBack(TInt aParam) const |
|
6477 { |
|
6478 return (*iFunction)(iPtr, aParam); |
|
6479 } |
|
6480 |
|
6481 /****************************************************************************** |
|
6482 Entry point |
5790 Entry point |
6483 ******************************************************************************/ |
5791 ******************************************************************************/ |
6484 DECLARE_STANDARD_EXTENSION() |
5792 DECLARE_STANDARD_EXTENSION() |
6485 { |
5793 { |
6486 __KTRACE_OPT(KBOOT,Kern::Printf("Starting LOCMEDIA extension")); |
5794 __KTRACE_OPT(KBOOT,Kern::Printf("Starting LOCMEDIA extension")); |
6487 |
5795 |
6488 // install the HAL function |
5796 // install the HAL function |
6489 TInt r=Kern::AddHalEntry(EHalGroupMedia,MediaHalFunction,NULL); |
5797 TInt r=Kern::AddHalEntry(EHalGroupMedia,MediaHalFunction,NULL); |
6490 |
|
6491 #ifdef __DEMAND_PAGING__ |
5798 #ifdef __DEMAND_PAGING__ |
6492 if (r==KErrNone) |
5799 if (r==KErrNone) |
6493 { |
5800 { |
6494 __KTRACE_OPT(KBOOT,Kern::Printf("Creating LocDrv device")); |
5801 __KTRACE_OPT(KBOOT,Kern::Printf("Creating LocDrv device")); |
6495 DLocalDriveFactory* device = new DLocalDriveFactory; |
5802 DLocalDriveFactory* device = new DLocalDriveFactory; |
6498 else |
5805 else |
6499 r=Kern::InstallLogicalDevice(device); |
5806 r=Kern::InstallLogicalDevice(device); |
6500 __KTRACE_OPT(KBOOT,Kern::Printf("Installing LocDrv device in kernel returned %d",r)); |
5807 __KTRACE_OPT(KBOOT,Kern::Printf("Installing LocDrv device in kernel returned %d",r)); |
6501 } |
5808 } |
6502 #endif // __DEMAND_PAGING__ |
5809 #endif // __DEMAND_PAGING__ |
6503 |
|
6504 return r; |
5810 return r; |
6505 } |
5811 } |
6506 |
5812 |
6507 |
5813 |