69 TPasswordStore* ThePasswordStore=NULL; |
69 TPasswordStore* ThePasswordStore=NULL; |
70 |
70 |
71 class DPrimaryMediaBase::DBody : public DBase |
71 class DPrimaryMediaBase::DBody : public DBase |
72 { |
72 { |
73 public: |
73 public: |
|
74 DBody(DPrimaryMediaBase& aPrimaryMediaBase); |
|
75 public: |
|
76 DPrimaryMediaBase& iPrimaryMediaBase; // ptr to parent |
74 TInt iPhysDevIndex; |
77 TInt iPhysDevIndex; |
75 TInt iRequestCount; |
78 TInt iRequestCount; |
76 #ifdef __DEMAND_PAGING__ |
79 #ifdef __DEMAND_PAGING__ |
77 DMediaPagingDevice* iPagingDevice; |
80 DMediaPagingDevice* iPagingDevice; |
78 TInt iPageSizeMsk; // Mask of page size (e.g. 4096-1 -> 4095) |
81 TInt iPageSizeMsk; // Mask of page size (e.g. 4096-1 -> 4095) |
79 TInt iMediaChanges; |
82 TInt iMediaChanges; |
80 #endif |
83 #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; |
81 }; |
95 }; |
82 |
96 |
83 #ifdef __DEMAND_PAGING__ |
97 #ifdef __DEMAND_PAGING__ |
84 DMediaPagingDevice* ThePagingDevices[KMaxLocalDrives]; |
98 DMediaPagingDevice* ThePagingDevices[KMaxLocalDrives]; |
85 DPrimaryMediaBase* TheRomPagingMedia = NULL; |
99 DPrimaryMediaBase* TheRomPagingMedia = NULL; |
86 DPrimaryMediaBase* TheDataPagingMedia = NULL; |
100 DPrimaryMediaBase* TheDataPagingMedia = NULL; |
|
101 TLocDrv* TheDataPagingDrive = NULL; |
87 TBool DataPagingDeviceRegistered = EFalse; |
102 TBool DataPagingDeviceRegistered = EFalse; |
88 class DPinObjectAllocator; |
103 class DPinObjectAllocator; |
89 DPinObjectAllocator* ThePinObjectAllocator = NULL; |
104 DPinObjectAllocator* ThePinObjectAllocator = NULL; |
90 |
105 |
91 // The paging media might share a DfcQ with other non-paging media (e.g. 2 MMC/SD cards sharing the same stack) |
106 // The paging media might share a DfcQ with other non-paging media (e.g. 2 MMC/SD cards sharing the same stack) |
92 // In this case, we need to avoid taking page faults on the non-paging media too, hence the need for these checks: |
107 // In this case, we need to avoid taking page faults on the non-paging media too, hence the need for these checks: |
93 inline TBool DataPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
108 inline TBool DataPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
94 {return TheDataPagingMedia && TheDataPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;} |
109 {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 |
95 inline TBool RomPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
120 inline TBool RomPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia) |
96 {return TheRomPagingMedia && TheRomPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;} |
121 {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 |
97 |
131 |
98 |
132 |
99 |
133 |
100 /* |
134 /* |
101 DPinObjectAllocator |
135 DPinObjectAllocator |
102 |
136 |
103 Internal class which contains : |
137 Internal class which contains : |
104 (1) a queue of pre-allocated TVirtualPinObject's; |
138 (1) a queue of pre-allocated TVirtualPinObject's; |
105 (2) a single pre-allocated DFragmentationPagingLock object: |
139 (2) a single pre-allocated DFragmentationPagingLock object: |
106 this may be used if there are no TVirtualPinObject's available or if Kern::PinVirtualMemory() fails |
140 this may be used if there are no TVirtualPinObject's available or if Kern::PinVirtualMemory() fails |
|
141 @internalTechnology |
107 */ |
142 */ |
108 NONSHARABLE_CLASS(DPinObjectAllocator) : public DBase |
143 NONSHARABLE_CLASS(DPinObjectAllocator) : public DBase |
109 { |
144 { |
110 public: |
145 public: |
111 /* |
146 /* |
258 } |
293 } |
259 |
294 |
260 #endif // __DEMAND_PAGING__ |
295 #endif // __DEMAND_PAGING__ |
261 |
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 |
263 /******************************************** |
390 /******************************************** |
264 * Local drive device base class |
391 * Local drive device base class |
265 ********************************************/ |
392 ********************************************/ |
266 DECLARE_EXTENSION_LDD() |
393 DECLARE_EXTENSION_LDD() |
267 { |
394 { |
1063 |
1167 |
1064 OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT2, this ); |
1168 OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT2, this ); |
1065 } |
1169 } |
1066 #endif // __DEMAND_PAGING__ |
1170 #endif // __DEMAND_PAGING__ |
1067 |
1171 |
1068 void DLocalDrive::NotifyChange(DPrimaryMediaBase& aPrimaryMedia, TBool aMediaChange) |
1172 void DLocalDrive::NotifyChange() |
1069 { |
1173 { |
1070 OstTraceExt2( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange;aPrimaryMedia=%x;aMediaChange=%d", (TUint) &aPrimaryMedia, aMediaChange ); |
1174 OstTrace0( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange"); |
1071 #ifndef __DEMAND_PAGING__ |
1175 |
1072 aPrimaryMedia; |
1176 |
1073 #endif |
1177 // Complete any notification request on media change |
1074 |
1178 DThread* pC=NULL; |
1075 // Complete any notification request on media change or power down |
1179 NKern::LockSystem(); |
1076 if (aMediaChange) |
1180 if (iCleanup.iThread) |
1077 { |
1181 { |
1078 DThread* pC=NULL; |
1182 pC=iCleanup.iThread; |
1079 NKern::LockSystem(); |
1183 pC->Open(); |
1080 if (iCleanup.iThread) |
1184 } |
1081 { |
1185 NKern::UnlockSystem(); |
1082 pC=iCleanup.iThread; |
1186 if (pC) |
1083 pC->Open(); |
1187 { |
1084 } |
1188 TBool b = ETrue; |
1085 NKern::UnlockSystem(); |
1189 // if change not yet queued, queue it now |
1086 if (pC) |
1190 if (iNotifyChangeRequest->IsReady()) |
1087 { |
1191 { |
1088 TBool b = ETrue; |
1192 *((TBool*) iNotifyChangeRequest->Buffer()) = b; |
1089 // if change not yet queued, queue it now |
1193 Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone); |
1090 if (iNotifyChangeRequest->IsReady()) |
1194 } |
1091 { |
1195 // If change has not even been requested by the client, maintain the pre-wdp behaviour |
1092 *((TBool*) iNotifyChangeRequest->Buffer()) = b; |
1196 // and write data immediately back to client (possibly taking a page fault) |
1093 Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone); |
1197 // N.B. Must NOT do this on data paging media |
1094 } |
|
1095 // If change has not even been requested by the client, maintain the pre-wdp behaviour |
|
1096 // and write data immediately back to client (possibly taking a page fault) |
|
1097 // N.B. Must NOT do this on data paging media |
|
1098 #ifdef __DEMAND_PAGING__ |
1198 #ifdef __DEMAND_PAGING__ |
1099 else if (!DataPagingDfcQ(&aPrimaryMedia)) |
1199 else if (!DataPagingDfcQ(iDrive->iPrimaryMedia)) |
1100 #else |
1200 #else |
1101 else |
1201 else |
1102 #endif |
1202 #endif |
1103 { |
1203 { |
1104 Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL); |
1204 Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL); |
1105 } |
1205 } |
1106 pC->AsyncClose(); |
1206 pC->AsyncClose(); |
1107 } |
|
1108 } |
1207 } |
1109 OstTraceFunctionExit1( DLOCALDRIVE_NOTIFYCHANGE_EXIT, this ); |
1208 OstTraceFunctionExit1( DLOCALDRIVE_NOTIFYCHANGE_EXIT, this ); |
|
1209 } |
|
1210 |
|
1211 // This function is called by the primary media when a media change occurs |
|
1212 TInt DLocalDrive::MediaChangeCallback(TAny* aLocalDrive, TInt /* aNotifyType*/) |
|
1213 { |
|
1214 ((DLocalDrive*) aLocalDrive)->NotifyChange(); |
|
1215 return KErrNone; |
1110 } |
1216 } |
1111 |
1217 |
1112 TLocalDriveCleanup::TLocalDriveCleanup() |
1218 TLocalDriveCleanup::TLocalDriveCleanup() |
1113 { |
1219 { |
1114 } |
1220 } |
1783 Otherwise, one of the other system wide error codes. |
2014 Otherwise, one of the other system wide error codes. |
1784 |
2015 |
1785 @see TLocDrvRequest |
2016 @see TLocDrvRequest |
1786 */ |
2017 */ |
1787 { |
2018 { |
1788 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this ); |
2019 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this ); |
1789 |
2020 |
1790 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::Request(%08x)",iMediaId,&aReq)); |
2021 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::Request(%08x)",iMediaId,&aReq)); |
1791 __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())); |
2022 __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())); |
1792 |
2023 |
1793 OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST, "reqId=%d; length=0x%lx; position=0x%lx; remote thread=0x%x", (TInt) aReq.Id(), (TUint) aReq.Length(), (TUint) aReq.Pos(), (TUint) aReq.RemoteThread()); |
2024 OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST, "reqId=%d; length=0x%lx; position=0x%lx; remote thread=0x%x", (TInt) aReq.Id(), (TUint) aReq.Length(), (TUint) aReq.Pos(), (TUint) aReq.RemoteThread()); |
1794 |
2025 |
1795 TInt reqId = aReq.Id(); |
2026 TInt reqId = aReq.Id(); |
1796 |
2027 |
1797 if (reqId == DLocalDrive::ECaps) |
2028 TInt r = HandleMediaNotPresent(aReq); |
1798 DefaultDriveCaps(*(TLocalDriveCapsV2*)aReq.RemoteDes()); // fill in stuff we know even if no media present |
2029 if (r != KErrNone) |
1799 |
2030 { |
1800 TInt r = QuickCheckStatus(); |
|
1801 if (r != KErrNone && aReq.Id()!=DLocalDrive::EForceMediaChange && // EForceMediaChange, and |
|
1802 aReq.Id()!=DLocalDrive::EReadPasswordStore && // Password store operations |
|
1803 aReq.Id()!=DLocalDrive::EWritePasswordStore && // do not require the media |
|
1804 aReq.Id()!=DLocalDrive::EPasswordStoreLengthInBytes) // to be ready.) |
|
1805 { |
|
1806 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_REQUEST_EXIT, this, r ); |
2031 OstTraceFunctionExitExt( DPRIMARYMEDIABASE_REQUEST_EXIT, this, r ); |
1807 return r; |
2032 return r; |
1808 } |
2033 } |
|
2034 |
1809 |
2035 |
1810 |
2036 |
1811 // for ERead & EWrite requests, get the linear address for pinning & DMA |
2037 // for ERead & EWrite requests, get the linear address for pinning & DMA |
1812 TUint8* linAddress = NULL; |
2038 TUint8* linAddress = NULL; |
1813 TClientBuffer clientBuffer; |
2039 TClientBuffer clientBuffer; |
2684 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS1, "DPrimaryMediaBase iMediaId=%d", iMediaId ); |
2926 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS1, "DPrimaryMediaBase iMediaId=%d", iMediaId ); |
2685 |
2927 |
2686 // we mustn't ever close the media driver if it's responsible for data paging as re-opening the drive |
2928 // we mustn't ever close the media driver if it's responsible for data paging as re-opening the drive |
2687 // would involve memory allocation which might cause deadlock if the kernel heap were to grow |
2929 // would involve memory allocation which might cause deadlock if the kernel heap were to grow |
2688 #ifdef __DEMAND_PAGING__ |
2930 #ifdef __DEMAND_PAGING__ |
2689 if (DataPagingDfcQ(this)) |
2931 if (DataPagingMedia(this)) |
2690 { |
2932 { |
2691 __KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for data paging media %08X", this)); |
2933 __KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for data paging media %08X", this)); |
2692 OstTrace1(TRACE_FLOW, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS_EXIT1, "CloseMediaDrivers aborting for data paging media 0x%08x", this); |
2934 OstTrace1(TRACE_FLOW, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS_EXIT1, "CloseMediaDrivers aborting for data paging media 0x%08x", this); |
2693 return; |
2935 return; |
2694 } |
2936 } |
2695 #endif |
2937 #endif |
2696 |
2938 |
2697 TInt i; |
2939 |
2698 for (i=0; i<KMaxLocalDrives; i++) |
2940 // Don't close any media extension drivers either, since it won't serve any purpose |
2699 { |
2941 // and keeping the driver open allows it to maintain internal state |
2700 TLocDrv* pL=TheDrives[i]; |
2942 if (iBody->iMediaExtension) |
|
2943 { |
|
2944 __KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for extension media %08X", this)); |
|
2945 return; |
|
2946 } |
|
2947 |
|
2948 |
|
2949 TDriveIterator driveIter; |
|
2950 for (TLocDrv* pL = driveIter.NextDrive(); pL != NULL; pL = driveIter.NextDrive()) |
|
2951 { |
2701 if (pL && pL->iPrimaryMedia==this) |
2952 if (pL && pL->iPrimaryMedia==this) |
2702 { |
2953 { |
2703 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",i)); |
2954 __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",driveIter.Index())); |
2704 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", i ); |
2955 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", driveIter.Index()); |
2705 if (aMedia == NULL || pL->iMedia == aMedia) |
2956 if (aMedia == NULL || pL->iMedia == aMedia) |
2706 { |
2957 { |
2707 pL->iMedia=NULL; |
2958 pL->iMedia=NULL; |
2708 } |
2959 } |
2709 } |
2960 } |
2710 } |
2961 } |
2711 for (i=iLastMediaId; i>=iMediaId; i--) |
2962 for (TInt i=iLastMediaId; i>=iMediaId; i--) |
2712 { |
2963 { |
2713 DMedia* pM=TheMedia[i]; |
2964 DMedia* pM=TheMedia[i]; |
2714 if (aMedia == NULL || pM == aMedia) |
2965 if (aMedia == NULL || pM == aMedia) |
2715 { |
2966 { |
2716 DMediaDriver* pD=pM->iDriver; |
2967 DMediaDriver* pD=pM->iDriver; |
3214 |
3464 |
3215 iWaitMedChg.CompleteAll(KErrNone); |
3465 iWaitMedChg.CompleteAll(KErrNone); |
3216 OstTraceFunctionExit1( DPRIMARYMEDIABASE_SETCLOSED_EXIT, this ); |
3466 OstTraceFunctionExit1( DPRIMARYMEDIABASE_SETCLOSED_EXIT, this ); |
3217 } |
3467 } |
3218 |
3468 |
3219 void DPrimaryMediaBase::NotifyClients(TBool aMediaChange,TLocDrv* aLocDrv) |
3469 void DPrimaryMediaBase::NotifyClients(TNotifyType aNotifyType, TLocDrv* aLocDrv) |
3220 |
3470 |
3221 // |
3471 // |
3222 // Notify all clients of a media change or power-down event |
3472 // Notify all clients of a media change or media present event |
3223 // |
3473 // |
3224 { |
3474 { |
3225 OstTraceFunctionEntryExt( DPRIMARYMEDIABASE_NOTIFYCLIENTS_ENTRY, this ); |
3475 OstTraceFunctionEntryExt( DPRIMARYMEDIABASE_NOTIFYCLIENTS_ENTRY, this ); |
3226 |
3476 |
3227 SDblQueLink* pL=iConnectionQ.iA.iNext; |
3477 SDblQueLink* pL=iConnectionQ.iA.iNext; |
3228 while (pL!=&iConnectionQ.iA) |
3478 while (pL!=&iConnectionQ.iA) |
3229 { |
3479 { |
3230 DLocalDrive* pD=_LOFF(pL,DLocalDrive,iLink); |
3480 // Get pointer to TCallBackLink |
|
3481 TCallBackLink* pCallBackLink = _LOFF(pL,TCallBackLink,iLink); |
|
3482 |
|
3483 // The link is embedded in either a TLocDrv or a DLocalDrive object; |
|
3484 // find out which one it is and then get TLocDrv pointer from that |
|
3485 __ASSERT_DEBUG(pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject || pCallBackLink->iObjectType == TCallBackLink::ETLocDrvObject, LOCM_FAULT()); |
|
3486 TLocDrv* locDrv; |
|
3487 if (pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject) |
|
3488 locDrv = ((DLocalDrive*) _LOFF(pCallBackLink,DLocalDrive, iMediaChangeObserver))->iDrive; |
|
3489 else |
|
3490 locDrv = ((TLocDrv*) _LOFF(pCallBackLink,TLocDrv, iMediaChangeObserver))->iNextDrive; |
|
3491 |
3231 // Issue the notification if the caller wants to notify all drives (aLocDrv == NULL) or |
3492 // Issue the notification if the caller wants to notify all drives (aLocDrv == NULL) or |
3232 // the specified drive matches this one |
3493 // the specified drive matches this one |
3233 if (aLocDrv == NULL || aLocDrv == pD->iDrive) |
3494 if (aLocDrv == NULL || aLocDrv == locDrv) |
3234 pD->NotifyChange(*this, aMediaChange); |
3495 pCallBackLink->CallBack(aNotifyType); |
|
3496 |
3235 pL=pL->iNext; |
3497 pL=pL->iNext; |
3236 } |
3498 } |
3237 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYCLIENTS_EXIT, this ); |
3499 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYCLIENTS_EXIT, this ); |
3238 } |
3500 } |
3239 |
3501 |
3247 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_ENTRY, this ); |
3509 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_ENTRY, this ); |
3248 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaChange state %d",iMediaId,iState)); |
3510 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaChange state %d",iMediaId,iState)); |
3249 |
3511 |
3250 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE, "iMediaId=%d; iState=%d", iMediaId, iState ); |
3512 OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE, "iMediaId=%d; iState=%d", iMediaId, iState ); |
3251 |
3513 |
3252 TInt state=iState; |
3514 // This should only be called in the context of the media thread |
3253 |
3515 __ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT()); |
3254 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
3516 |
3255 |
3517 MediaChange(); |
3256 #ifdef __DEMAND_PAGING__ |
|
3257 iBody->iMediaChanges++; |
|
3258 |
|
3259 // As data paging media never close, need to ensure the media driver cancels |
|
3260 // any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange(). |
|
3261 // DMediaDriver::NotifyPowerDown() should do this |
|
3262 if(DataPagingDfcQ(this)) |
|
3263 NotifyPowerDown(); |
|
3264 #endif |
|
3265 |
|
3266 // complete any outstanding requests with KErrNotReady |
|
3267 // and any force media change requests with KErrNone |
|
3268 SetClosed(KErrNotReady); |
|
3269 |
|
3270 // close all media drivers on this device |
|
3271 if (state>=EOpening) |
|
3272 { |
|
3273 CloseMediaDrivers(); |
|
3274 } |
|
3275 |
3518 |
3276 // notify all connections that media change has occurred |
3519 // notify all connections that media change has occurred |
3277 NotifyClients(ETrue); |
3520 NotifyClients(EMediaChange); |
3278 |
3521 |
3279 // complete any force media change requests |
3522 // complete any force media change requests |
3280 iWaitMedChg.CompleteAll(KErrNone); |
3523 iWaitMedChg.CompleteAll(KErrNone); |
3281 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_EXIT, this ); |
3524 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_EXIT, this ); |
3282 } |
3525 } |
3412 // if ready, media driver should complete current request |
3653 // if ready, media driver should complete current request |
3413 CompleteCurrent(KErrNotReady); |
3654 CompleteCurrent(KErrNotReady); |
3414 } |
3655 } |
3415 CloseMediaDrivers(); |
3656 CloseMediaDrivers(); |
3416 SetClosed(KErrNotReady); |
3657 SetClosed(KErrNotReady); |
3417 NotifyClients(EFalse); |
|
3418 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYEMERGENCYPOWERDOWN_EXIT, this ); |
3658 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYEMERGENCYPOWERDOWN_EXIT, this ); |
|
3659 } |
|
3660 |
|
3661 |
|
3662 /** |
|
3663 Called by NotifyMediaPresent() and NotifyMediaChange() to ensure the media is in the correct state |
|
3664 */ |
|
3665 void DPrimaryMediaBase::MediaChange() |
|
3666 { |
|
3667 // Media has been inserted, so we need to cancel any outstanding requests and |
|
3668 // ensure that the partition info is read again |
|
3669 TInt state = iState; |
|
3670 |
|
3671 __ASSERT_DEBUG(iBody, LOCM_FAULT()); |
|
3672 |
|
3673 #ifdef __DEMAND_PAGING__ |
|
3674 iBody->iMediaChanges++; |
|
3675 |
|
3676 // As data paging media never close, need to ensure the media driver cancels |
|
3677 // any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange(). |
|
3678 // DMediaDriver::NotifyPowerDown() should do this |
|
3679 if (DataPagingMedia(this)) |
|
3680 NotifyPowerDown(); |
|
3681 #endif |
|
3682 |
|
3683 // complete any outstanding requests with KErrNotReady |
|
3684 // and any force media change requests with KErrNone |
|
3685 SetClosed(KErrNotReady); |
|
3686 |
|
3687 // close all media drivers on this device |
|
3688 if (state>=EOpening) |
|
3689 { |
|
3690 CloseMediaDrivers(); |
|
3691 } |
3419 } |
3692 } |
3420 |
3693 |
3421 EXPORT_C void DPrimaryMediaBase::NotifyMediaPresent() |
3694 EXPORT_C void DPrimaryMediaBase::NotifyMediaPresent() |
3422 /** |
3695 /** |
3423 Notifies clients of a media change by calling NotifyClients ( ) function to indicate that media is present. |
3696 Notifies clients of a media change by calling NotifyClients ( ) function to indicate that media is present. |
3424 */ |
3697 */ |
3425 { |
3698 { |
3426 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_ENTRY, this ); |
3699 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_ENTRY, this ); |
3427 NotifyClients(ETrue); |
3700 __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaPresent state %d",iMediaId,iState)); |
|
3701 |
|
3702 // This should only be called in the context of the media thread |
|
3703 __ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT()); |
|
3704 |
|
3705 MediaChange(); |
|
3706 |
|
3707 NotifyClients(EMediaPresent); |
3428 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_EXIT, this ); |
3708 OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_EXIT, this ); |
3429 } |
3709 } |
3430 |
3710 |
3431 EXPORT_C TInt DPrimaryMediaBase::DoInCritical() |
3711 EXPORT_C TInt DPrimaryMediaBase::DoInCritical() |
3432 /** |
3712 /** |
4647 { |
4948 { |
4648 OstTraceFunctionEntry0( LOCDRV_REGISTERMEDIADEVICE_ENTRY ); |
4949 OstTraceFunctionEntry0( LOCDRV_REGISTERMEDIADEVICE_ENTRY ); |
4649 // Create TLocDrv / DMedia objects to handle a media device |
4950 // Create TLocDrv / DMedia objects to handle a media device |
4650 __KTRACE_OPT(KBOOT,Kern::Printf("RegisterMediaDevice %lS dev=%1d #drives=%d 1st=%d PM=%08x #media=%d",&aName,aDevice,aDriveCount,*aDriveList,aPrimaryMedia,aNumMedia)); |
4951 __KTRACE_OPT(KBOOT,Kern::Printf("RegisterMediaDevice %lS dev=%1d #drives=%d 1st=%d PM=%08x #media=%d",&aName,aDevice,aDriveCount,*aDriveList,aPrimaryMedia,aNumMedia)); |
4651 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 ); |
4952 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 ); |
4652 |
4953 |
4653 const TInt* p=aDriveList; |
|
4654 TInt i; |
|
4655 TInt r=0; |
|
4656 if (UsedMedia+aNumMedia>KMaxLocalDrives) |
4954 if (UsedMedia+aNumMedia>KMaxLocalDrives) |
4657 { |
4955 { |
4658 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT1, "< KErrInUse"); |
4956 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT1, "< KErrInUse"); |
4659 return KErrInUse; |
4957 return KErrInUse; |
4660 } |
4958 } |
4661 for (i=0; i<aDriveCount; ++i) |
4959 |
4662 { |
4960 // make a local copy of the name |
4663 TInt drv = *p++; |
|
4664 // -1 means not used; this is to enable Dual-slot MMC support |
|
4665 if (drv == -1) |
|
4666 continue; |
|
4667 __KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv)); |
|
4668 OstTrace1( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE2, "Registering drive=%d", drv ); |
|
4669 if (TheDrives[drv]) |
|
4670 { |
|
4671 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv)); |
|
4672 OstTrace1( TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT2, "< Drive %d already in use; KErrInUse", drv); |
|
4673 return KErrInUse; |
|
4674 } |
|
4675 } |
|
4676 HBuf* pN=HBuf::New(aName); |
4961 HBuf* pN=HBuf::New(aName); |
4677 if (!pN) |
4962 if (!pN) |
4678 { |
4963 { |
4679 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT3, "< KErrNoMemory"); |
4964 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT3, "< KErrNoMemory"); |
4680 return KErrNoMemory; |
4965 return KErrNoMemory; |
4681 } |
4966 } |
4682 TInt lastMedia=UsedMedia+aNumMedia-1; |
4967 |
|
4968 // Register the primary media and any secondary media |
|
4969 TInt lastMedia = UsedMedia+aNumMedia-1; |
|
4970 TInt i; |
|
4971 TInt r=0; |
4683 for (i=UsedMedia; i<=lastMedia; ++i) |
4972 for (i=UsedMedia; i<=lastMedia; ++i) |
4684 { |
4973 { |
4685 if (i==UsedMedia) |
4974 if (i==UsedMedia) |
4686 TheMedia[i]=aPrimaryMedia; |
4975 TheMedia[i]=aPrimaryMedia; |
4687 else |
4976 else |
4698 { |
4987 { |
4699 OstTrace1(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT5, "< retval=%d", r); |
4988 OstTrace1(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT5, "< retval=%d", r); |
4700 return r; |
4989 return r; |
4701 } |
4990 } |
4702 } |
4991 } |
4703 |
|
4704 __KTRACE_OPT(KBOOT,Kern::Printf("FirstMedia %d LastMedia %d",UsedMedia,lastMedia)); |
4992 __KTRACE_OPT(KBOOT,Kern::Printf("FirstMedia %d LastMedia %d",UsedMedia,lastMedia)); |
4705 OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE4, "FirstMedia=%d; LastMedia=%d", UsedMedia, lastMedia ); |
4993 OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE4, "FirstMedia=%d; LastMedia=%d", UsedMedia, lastMedia ); |
4706 UsedMedia+=aNumMedia; |
4994 UsedMedia+=aNumMedia; |
4707 p=aDriveList; |
4995 |
|
4996 if (__IS_EXTENSION(aDevice)) |
|
4997 aPrimaryMedia->iBody->iMediaExtension = ETrue; |
|
4998 |
|
4999 // Register the drives |
|
5000 const TInt* p=aDriveList; |
4708 for (i=0; i<aDriveCount; ++i) |
5001 for (i=0; i<aDriveCount; ++i) |
4709 { |
5002 { |
4710 TInt drv=*p++; |
5003 TInt drv = *p++; |
|
5004 // -1 means not used; this is to enable Dual-slot MMC support |
4711 if (drv == -1) |
5005 if (drv == -1) |
4712 continue; |
5006 continue; |
4713 TLocDrv* pL=new TLocDrv(drv); |
5007 |
4714 if (!pL) |
5008 __KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv)); |
4715 { |
5009 if (!__IS_EXTENSION(aDevice) && TheDrives[drv]) |
|
5010 { |
|
5011 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv)); |
|
5012 return KErrInUse; |
|
5013 } |
|
5014 else if (__IS_EXTENSION(aDevice) && !TheDrives[drv]) |
|
5015 { |
|
5016 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d not initialized", drv)); |
|
5017 return KErrNotReady; |
|
5018 } |
|
5019 |
|
5020 TLocDrv* pNewDrive = new TLocDrv(drv); |
|
5021 if (!pNewDrive) |
|
5022 { |
4716 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT6, "< KErrNoMemory"); |
5023 OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT6, "< KErrNoMemory"); |
4717 return KErrNoMemory; |
5024 return KErrNoMemory; |
4718 } |
5025 } |
4719 TheDrives[drv]=pL; |
5026 |
4720 DriveNames[drv]=pN; |
5027 |
4721 pL->iPrimaryMedia=aPrimaryMedia; |
5028 TLocDrv* pOldDrive = TheDrives[drv]; |
4722 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pL)); |
5029 aPrimaryMedia->iBody->iRegisteredDriveMask|= (0x1 << drv); |
4723 OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE5, "Drive=%d; TLocDrv 0x%08x;", (TInt) drv, (TUint) pL ); |
5030 pNewDrive->iNextDrive = pOldDrive; |
4724 } |
5031 |
|
5032 TheDrives[drv] = pNewDrive; |
|
5033 DriveNames[drv] = pN; |
|
5034 pNewDrive->iPrimaryMedia = aPrimaryMedia; |
|
5035 |
|
5036 |
|
5037 if (pOldDrive) |
|
5038 { |
|
5039 TInt r = pOldDrive->iPrimaryMedia->Connect(pNewDrive); |
|
5040 if (r != KErrNone) |
|
5041 return r; |
|
5042 |
|
5043 #ifdef __DEMAND_PAGING__ |
|
5044 // If we've hooked a drive letter which is being used for ROM paging by a media driver |
|
5045 // which does not report the ROM partition, then we need to change iFirstLocalDriveNumber |
|
5046 // so that ROM page-in requests go directly to that driver |
|
5047 DMediaPagingDevice* oldPagingDevice = pOldDrive->iPrimaryMedia->iBody->iPagingDevice; |
|
5048 if (oldPagingDevice && |
|
5049 (oldPagingDevice->iType & DPagingDevice::ERom) && |
|
5050 oldPagingDevice->iRomPagingDriveNumber == KErrNotFound && |
|
5051 oldPagingDevice->iFirstLocalDriveNumber == drv) |
|
5052 { |
|
5053 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: hooking ROM paging device with no defined ROM partition")); |
|
5054 TInt n; |
|
5055 for (n=0; n<KMaxLocalDrives; ++n) |
|
5056 { |
|
5057 if(TheDrives[n] && TheDrives[n]->iPrimaryMedia == pOldDrive->iPrimaryMedia) |
|
5058 { |
|
5059 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: Changing iFirstLocalDriveNumber from %d to %d", oldPagingDevice->iFirstLocalDriveNumber, n)); |
|
5060 oldPagingDevice->iFirstLocalDriveNumber = n; |
|
5061 break; |
|
5062 } |
|
5063 } |
|
5064 __ASSERT_ALWAYS(n < KMaxLocalDrives, LOCM_FAULT()); |
|
5065 } |
|
5066 #endif |
|
5067 |
|
5068 } |
|
5069 |
|
5070 __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pNewDrive)); |
|
5071 } |
|
5072 |
4725 |
5073 |
4726 OstTraceFunctionExit0( LOCDRV_REGISTERMEDIADEVICE_EXIT7 ); |
5074 OstTraceFunctionExit0( LOCDRV_REGISTERMEDIADEVICE_EXIT7 ); |
4727 return KErrNone; |
5075 return KErrNone; |
4728 } |
5076 } |
4729 |
5077 |
4805 or one of the other system-wide error codes. |
5153 or one of the other system-wide error codes. |
4806 */ |
5154 */ |
4807 EXPORT_C TInt LocDrv::RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages) |
5155 EXPORT_C TInt LocDrv::RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages) |
4808 { |
5156 { |
4809 OstTraceFunctionEntry0( LOCDRV_REGISTERPAGINGDEVICE_ENTRY ); |
5157 OstTraceFunctionEntry0( LOCDRV_REGISTERPAGINGDEVICE_ENTRY ); |
|
5158 // SETDEBUGFLAG(KLOCDPAGING); |
4810 |
5159 |
4811 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf(">RegisterPagingDevice: paging type=%d PM=0x%x read shift=%d",aPagingType,aPrimaryMedia,aReadShift)); |
5160 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf(">RegisterPagingDevice: paging type=%d PM=0x%x read shift=%d",aPagingType,aPrimaryMedia,aReadShift)); |
4812 OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE1, "aPagingType=%d; aPrimaryMedia=0x%x; aReadShift=%d", (TInt) aPagingType, (TUint) aPrimaryMedia, (TInt) aReadShift); |
5161 OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE1, "aPagingType=%d; aPrimaryMedia=0x%x; aReadShift=%d", (TInt) aPagingType, (TUint) aPrimaryMedia, (TInt) aReadShift); |
4813 |
5162 |
4814 TInt i; |
5163 TInt i = 0; |
4815 |
5164 |
4816 if(!aPagingType || (aPagingType&~(DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData))) |
5165 if(!aPagingType || (aPagingType&~(DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData))) |
4817 { |
5166 { |
4818 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting")); |
5167 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting")); |
4819 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument"); |
5168 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument"); |
4820 return KErrArgument; |
5169 return KErrArgument; |
4821 } |
5170 } |
4822 |
5171 |
4823 |
5172 |
4824 |
5173 // Check for duplicate drives |
4825 for(i=0; i<KMaxLocalDrives; i++) |
5174 if (!aPrimaryMedia->iBody->iMediaExtension) |
4826 { |
5175 { |
4827 if (ThePagingDevices[i] == NULL) |
5176 for(i=0; i<KMaxLocalDrives; i++) |
4828 continue; |
5177 { |
4829 if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) && (aPagingType & DPagingDevice::ERom)) |
5178 if (ThePagingDevices[i] == NULL) |
4830 { |
5179 continue; |
4831 aPagingType&=~DPagingDevice::ERom; // already have a ROM paging device |
5180 if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) && (aPagingType & DPagingDevice::ERom)) |
4832 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i)); |
5181 { |
4833 } |
5182 aPagingType&=~DPagingDevice::ERom; // already have a ROM paging device |
4834 if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData)) |
5183 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i)); |
4835 { |
5184 } |
4836 aPagingType&=~DPagingDevice::EData; // already have a Data paging device |
5185 if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData)) |
4837 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i)); |
5186 { |
|
5187 aPagingType&=~DPagingDevice::EData; // already have a Data paging device |
|
5188 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i)); |
|
5189 } |
4838 } |
5190 } |
4839 } |
5191 } |
4840 |
5192 |
4841 |
5193 |
4842 if (aPagingType == 0) |
5194 if (aPagingType == 0) |
4913 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("DMediaPagingDevice(), firstLocalDriveNumber %d", firstLocalDriveNumber)); |
5265 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("DMediaPagingDevice(), firstLocalDriveNumber %d", firstLocalDriveNumber)); |
4914 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE3, "firstLocalDriveNumber=%d", firstLocalDriveNumber ); |
5266 OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE3, "firstLocalDriveNumber=%d", firstLocalDriveNumber ); |
4915 |
5267 |
4916 // Send an ECaps message to wake up the media driver & ensure all partitions are |
5268 // Send an ECaps message to wake up the media driver & ensure all partitions are |
4917 // reported, then search for paged-data or paged-ROM partitions |
5269 // reported, then search for paged-data or paged-ROM partitions |
|
5270 // NB: older media drivers supporting ROM and/or code paging only may not have started their DFC queues, |
|
5271 // so for these media drivers, use the first local drive supported for ROM-pagin-in requests and |
|
5272 // assume the media driver itself will adjust the request position internally to match the ROM partition |
|
5273 // @see DMediaPagingDevice::Read() |
4918 if ((aPagingType & DPagingDevice::EData) || |
5274 if ((aPagingType & DPagingDevice::EData) || |
4919 (aPagingType & DPagingDevice::ERom && aPrimaryMedia->iDfcQ && aPrimaryMedia->iMsgQ.iReady)) |
5275 (aPagingType & DPagingDevice::ERom && aPrimaryMedia->iDfcQ && aPrimaryMedia->iMsgQ.iReady)) |
4920 { |
5276 { |
4921 // the message queue must have been started already (by the media driver calling iMsgQ.Receive()) |
5277 // the message queue must have been started already (by the media driver calling iMsgQ.Receive()) |
4922 // otherwise we can't send the DLocalDrive::EQueryDevice request |
5278 // otherwise we can't send the DLocalDrive::ECaps request |
4923 if (aPrimaryMedia->iDfcQ && !aPrimaryMedia->iMsgQ.iReady) |
5279 if (!aPrimaryMedia->iDfcQ || !aPrimaryMedia->iMsgQ.iReady) |
4924 { |
5280 { |
4925 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Message queue not started")); |
5281 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Message queue not started")); |
4926 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT8, "< RegisterPagingDevice: Message queue not started; KErrNotReady"); |
5282 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT8, "< RegisterPagingDevice: Message queue not started; KErrNotReady"); |
4927 return KErrNotReady; |
5283 return KErrNotReady; |
4928 } |
5284 } |
4965 for (i=0; i<KMaxLocalDrives; ++i) |
5321 for (i=0; i<KMaxLocalDrives; ++i) |
4966 { |
5322 { |
4967 drive = TheDrives[i]; |
5323 drive = TheDrives[i]; |
4968 if(drive && drive->iPrimaryMedia == aPrimaryMedia) |
5324 if(drive && drive->iPrimaryMedia == aPrimaryMedia) |
4969 { |
5325 { |
4970 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x size %x", i, drive->iPartitionType, I64LOW(drive->iPartitionLen))); |
5326 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x base %lx size %lx name %lS", i, drive->iPartitionType, drive->iPartitionBaseAddr, drive->iPartitionLen, DriveNames[i] ? DriveNames[i] : &KNullDesC8)); |
4971 // ROM partition ? |
5327 // ROM partition ? |
4972 if ((romPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypeROM)) |
5328 if ((romPagingDriveNumber == KErrNotFound) && |
|
5329 (drive->iPartitionType == KPartitionTypeROM) && |
|
5330 (aPagingType & DPagingDevice::ERom)) |
4973 { |
5331 { |
4974 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found ROM partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
5332 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found ROM partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
4975 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)); |
5333 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)); |
4976 romPagingDriveNumber = i; |
5334 romPagingDriveNumber = i; |
4977 } |
5335 } |
4978 // swap partition ? |
5336 // swap partition ? |
4979 else if ((dataPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypePagedData)) |
5337 else if ((dataPagingDriveNumber == KErrNotFound) && |
|
5338 (drive->iPartitionType == KPartitionTypePagedData) && |
|
5339 (aPagingType & DPagingDevice::EData)) |
4980 { |
5340 { |
4981 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
5341 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen))); |
4982 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) ); |
5342 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) ); |
4983 dataPagingDriveNumber = i; |
5343 dataPagingDriveNumber = i; |
|
5344 TheDataPagingDrive = drive; |
4984 swapSize = drive->iPartitionLen >> aReadShift; |
5345 swapSize = drive->iPartitionLen >> aReadShift; |
4985 } |
5346 } |
4986 } |
5347 } |
4987 } |
5348 } |
4988 |
5349 |
5004 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory"); |
5365 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory"); |
5005 return KErrNoMemory; |
5366 return KErrNoMemory; |
5006 } |
5367 } |
5007 |
5368 |
5008 pagingDevice->iType = aPagingType; |
5369 pagingDevice->iType = aPagingType; |
|
5370 if (aPrimaryMedia->iBody->iMediaExtension) |
|
5371 pagingDevice->iType|= DPagingDevice::EMediaExtension; |
|
5372 |
5009 pagingDevice->iReadUnitShift = aReadShift; |
5373 pagingDevice->iReadUnitShift = aReadShift; |
5010 |
5374 |
5011 pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber; |
5375 pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber; |
5012 pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber; |
5376 pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber; |
5013 |
5377 |
5014 pagingDevice->iDataPagingDriveNumber = dataPagingDriveNumber; |
5378 pagingDevice->iDataPagingDriveNumber = dataPagingDriveNumber; |
5015 pagingDevice->iSwapSize = swapSize; |
5379 pagingDevice->iSwapSize = swapSize; |
5016 |
5380 |
5017 #ifdef __DEBUG_DEMAND_PAGING__ |
5381 #ifdef __DEBUG_DEMAND_PAGING__ |
5018 Kern::Printf("PagingDevice :"); |
5382 Kern::Printf("PagingDevice :"); |
5019 Kern::Printf("iType 0x%x\n", pagingDevice->iType); |
5383 Kern::Printf("Name %lS", firstLocalDriveNumber >= 0 && DriveNames[firstLocalDriveNumber] ? DriveNames[firstLocalDriveNumber] : &KNullDesC8); |
5020 Kern::Printf("iReadUnitShift 0x%x\n", pagingDevice->iReadUnitShift); |
5384 Kern::Printf("iType 0x%x", pagingDevice->iType); |
5021 Kern::Printf("iFirstLocalDriveNumber 0x%x\n", pagingDevice->iFirstLocalDriveNumber); |
5385 Kern::Printf("iReadUnitShift 0x%x", pagingDevice->iReadUnitShift); |
5022 Kern::Printf("iRomPagingDriveNumber 0x%x\n", pagingDevice->iRomPagingDriveNumber); |
5386 Kern::Printf("iFirstLocalDriveNumber 0x%x", pagingDevice->iFirstLocalDriveNumber); |
5023 Kern::Printf("iDataPagingDriveNumber 0x%x\n", pagingDevice->iDataPagingDriveNumber); |
5387 Kern::Printf("iRomPagingDriveNumber 0x%x", pagingDevice->iRomPagingDriveNumber); |
5024 Kern::Printf("iSwapSize 0x%x\n", pagingDevice->iSwapSize); |
5388 Kern::Printf("iDataPagingDriveNumber 0x%x", pagingDevice->iDataPagingDriveNumber); |
|
5389 Kern::Printf("iSwapSize 0x%x", pagingDevice->iSwapSize); |
5025 #endif |
5390 #endif |
5026 |
5391 |
5027 |
5392 |
5028 // This table is indexed by DPagingDevice::TType |
5393 // This table is indexed by DPagingDevice::TType |
5029 const char* DeviceName[] = |
5394 const char* DeviceName[] = |
5040 |
5405 |
5041 |
5406 |
5042 if(aPagingType & DPagingDevice::ECode) |
5407 if(aPagingType & DPagingDevice::ECode) |
5043 { |
5408 { |
5044 for (i=0; i<aDriveCount; ++i) |
5409 for (i=0; i<aDriveCount; ++i) |
5045 pagingDevice->iDrivesSupported|=(0x1<<aPagingDriveList[i]); |
5410 pagingDevice->iDrivesSupported |= (0x1<<aPagingDriveList[i]); |
5046 } |
5411 } |
5047 pagingDevice->iName = DeviceName[aPagingType]; |
5412 pagingDevice->iName = DeviceName[aPagingType]; |
5048 |
5413 |
|
5414 // If ThePinObjectAllocator has already been created with a smaller number of pages, |
|
5415 // delete it & then re-create it |
|
5416 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: ThePinObjectAllocator %x", ThePinObjectAllocator)); |
|
5417 if (ThePinObjectAllocator && ThePinObjectAllocator->iFragmentGranularity < Kern::RoundToPageSize(1) * aNumPages) |
|
5418 { |
|
5419 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Recreating ThePinObjectAllocator...")); |
|
5420 delete ThePinObjectAllocator; |
|
5421 ThePinObjectAllocator = NULL; |
|
5422 } |
|
5423 |
|
5424 |
|
5425 TInt r; |
5049 if (ThePinObjectAllocator == NULL) |
5426 if (ThePinObjectAllocator == NULL) |
|
5427 { |
5050 ThePinObjectAllocator = new DPinObjectAllocator(); |
5428 ThePinObjectAllocator = new DPinObjectAllocator(); |
5051 if(!ThePinObjectAllocator) |
5429 if(!ThePinObjectAllocator) |
5052 { |
5430 { |
5053 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator")); |
5431 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator")); |
5054 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory"); |
5432 OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory"); |
5055 return KErrNoMemory; |
5433 return KErrNoMemory; |
5056 } |
5434 } |
5057 TInt r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages); |
5435 r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages); |
5058 if (r != KErrNone) |
5436 if (r != KErrNone) |
5059 { |
5437 { |
5060 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator")); |
5438 __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator")); |
5061 OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r); |
5439 OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r); |
5062 return r; |
5440 return r; |
|
5441 } |
5063 } |
5442 } |
5064 |
5443 |
5065 |
5444 |
5066 // Register our DPagingDevice with the Kernel |
5445 // Register our DPagingDevice with the Kernel |
5067 r=Kern::InstallPagingDevice(pagingDevice); |
5446 r=Kern::InstallPagingDevice(pagingDevice); |
5735 } |
6097 } |
5736 } |
6098 } |
5737 |
6099 |
5738 |
6100 |
5739 /****************************************************************************** |
6101 /****************************************************************************** |
|
6102 DMediaDriverExtension base class |
|
6103 ******************************************************************************/ |
|
6104 |
|
6105 EXPORT_C DMediaDriverExtension::DMediaDriverExtension(TInt aMediaId) : |
|
6106 DMediaDriver(aMediaId) |
|
6107 { |
|
6108 } |
|
6109 |
|
6110 /** |
|
6111 */ |
|
6112 EXPORT_C DMediaDriverExtension::~DMediaDriverExtension() |
|
6113 { |
|
6114 } |
|
6115 |
|
6116 /** |
|
6117 Closes the media driver. |
|
6118 |
|
6119 This default implementation simply deletes this DMediaDriverExtension object. |
|
6120 |
|
6121 Media drivers can provide their own implementation, which gives them |
|
6122 the opportunity to clean up resources before closure; for example, |
|
6123 cancelling a DFC. |
|
6124 Any replacement function must call this base class function as |
|
6125 the last instruction. |
|
6126 */ |
|
6127 EXPORT_C void DMediaDriverExtension::Close() |
|
6128 { |
|
6129 DMediaDriver::Close(); |
|
6130 } |
|
6131 |
|
6132 /** |
|
6133 DoDrivePartitionInfo() |
|
6134 |
|
6135 Fills out the passed TPartitionInfo object with information from the attached drives |
|
6136 */ |
|
6137 EXPORT_C TInt DMediaDriverExtension::DoDrivePartitionInfo(TPartitionInfo& aInfo) |
|
6138 { |
|
6139 memclr(&aInfo, sizeof(aInfo)); |
|
6140 aInfo.iPartitionCount = 0; |
|
6141 aInfo.iMediaSizeInBytes = 0; |
|
6142 |
|
6143 TDriveIterator driveIter; |
|
6144 for (TLocDrv* drv = driveIter.NextDrive(); drv != NULL; drv = driveIter.NextDrive()) |
|
6145 { |
|
6146 if (drv && drv->iPrimaryMedia == iPrimaryMedia) |
|
6147 { |
|
6148 TLocDrv* attachedDrive = drv->iNextDrive; |
|
6149 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6150 TLocDrvRequest m; |
|
6151 memclr(&m, sizeof(m)); |
|
6152 |
|
6153 TBuf8<KMaxLocalDriveCapsLength> capsBuf; |
|
6154 capsBuf.SetMax(); |
|
6155 capsBuf.FillZ(); |
|
6156 m.Drive() = attachedDrive; |
|
6157 m.Id() = DLocalDrive::ECaps; |
|
6158 m.RemoteDes() = (TAny*)capsBuf.Ptr(); |
|
6159 m.Length() = KMaxLocalDriveCapsLength; |
|
6160 TInt r = attachedDrive->iPrimaryMedia->Request(m); |
|
6161 |
|
6162 __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("DMediaDriverExtension::PartitionInfo(ECaps: i %d: r %d ", driveIter.Index(), r)); |
|
6163 |
|
6164 // NB The ECaps call might legitimately fail if one of the attached drives is removable |
|
6165 // If this happens, just ignore & proceed to the next attached drive |
|
6166 if (r == KErrNone) |
|
6167 { |
|
6168 aInfo.iEntry[aInfo.iPartitionCount] = *attachedDrive; |
|
6169 // Set the media size to be that of the largest attached media |
|
6170 // This is only needed to ensure that the test in TLocDrvRequest::CheckAndAdjustForPartition() |
|
6171 // with the ELocDrvWholeMedia flag set succeeds: A further check on whether a request's |
|
6172 // position & length are outside the media will be made when its is delievered to the attached media.... |
|
6173 aInfo.iMediaSizeInBytes = Max( |
|
6174 aInfo.iMediaSizeInBytes, |
|
6175 ((TLocalDriveCapsV4*) capsBuf.Ptr())->MediaSizeInBytes()); |
|
6176 } |
|
6177 |
|
6178 |
|
6179 aInfo.iPartitionCount++; |
|
6180 } |
|
6181 } |
|
6182 |
|
6183 return KErrNone; |
|
6184 } |
|
6185 |
|
6186 /** |
|
6187 ForwardRequest() - |
|
6188 |
|
6189 forwards the request onto the next attached drive in the chain |
|
6190 */ |
|
6191 EXPORT_C TInt DMediaDriverExtension::ForwardRequest(TLocDrvRequest& aRequest) |
|
6192 { |
|
6193 TLocDrv* drive = aRequest.Drive(); |
|
6194 TLocDrv* attachedDrive = drive->iNextDrive; |
|
6195 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6196 aRequest.Drive() = attachedDrive; |
|
6197 |
|
6198 |
|
6199 TInt r = attachedDrive->iPrimaryMedia->HandleMediaNotPresent(aRequest); |
|
6200 if (r != KErrNone) |
|
6201 { |
|
6202 return r; |
|
6203 } |
|
6204 |
|
6205 aRequest.Forward(&attachedDrive->iPrimaryMedia->iMsgQ, EFalse); |
|
6206 return KErrNone; |
|
6207 } |
|
6208 |
|
6209 |
|
6210 TInt DMediaDriverExtension::SendRequest(TInt aReqId, TBool aPagingRequest, TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6211 { |
|
6212 __ASSERT_DEBUG(aLen > 0, LOCM_FAULT()); |
|
6213 |
|
6214 // Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice() |
|
6215 if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber))) |
|
6216 return KErrArgument; |
|
6217 |
|
6218 TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia); |
|
6219 __ASSERT_DEBUG(drive, LOCM_FAULT()); |
|
6220 TLocDrv* attachedDrive = drive->iNextDrive; |
|
6221 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6222 |
|
6223 TLocDrvRequest request; |
|
6224 memclr(&request, sizeof(request)); |
|
6225 |
|
6226 request.Drive() = attachedDrive; |
|
6227 request.Id() = aReqId; |
|
6228 request.Length() = aLen; |
|
6229 request.RemoteDes() = (TAny*) aData; |
|
6230 request.Pos() = aPos; |
|
6231 request.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EAdjusted; |
|
6232 |
|
6233 #ifdef __DEMAND_PAGING__ |
|
6234 if (aPagingRequest) |
|
6235 { |
|
6236 request.Flags()|= TLocDrvRequest::EPaging; |
|
6237 // If the buffer is page aligned, use SendToMainQueueDfcAndBlock() as this |
|
6238 // is more efficient if the attached drive use DMA. |
|
6239 const TInt KPageSizeMask = 4096-1; |
|
6240 if (aData & KPageSizeMask) |
|
6241 { |
|
6242 return attachedDrive->iPrimaryMedia->SendReceive(request, aData); |
|
6243 } |
|
6244 else |
|
6245 { |
|
6246 attachedDrive->iPrimaryMedia->iBody->iPagingDevice->SendToMainQueueDfcAndBlock(&request); |
|
6247 return 0; |
|
6248 } |
|
6249 } |
|
6250 #else |
|
6251 aPagingRequest; |
|
6252 #endif |
|
6253 |
|
6254 return attachedDrive->iPrimaryMedia->SendReceive(request, aData); |
|
6255 } |
|
6256 |
|
6257 |
|
6258 /** |
|
6259 Read() - |
|
6260 |
|
6261 reads data from the next attached drive in the chain |
|
6262 |
|
6263 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6264 media, not the partition |
|
6265 */ |
|
6266 EXPORT_C TInt DMediaDriverExtension::Read(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6267 { |
|
6268 return SendRequest(DLocalDrive::ERead, EFalse, aDriveNumber, aPos, aData, aLen); |
|
6269 } |
|
6270 |
|
6271 /** |
|
6272 Write() - |
|
6273 |
|
6274 writes data to the next attached drive in the chain |
|
6275 |
|
6276 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6277 media, not the partition |
|
6278 */ |
|
6279 EXPORT_C TInt DMediaDriverExtension::Write(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6280 { |
|
6281 return SendRequest(DLocalDrive::EWrite, EFalse, aDriveNumber, aPos, aData, aLen); |
|
6282 } |
|
6283 |
|
6284 |
|
6285 #ifdef __DEMAND_PAGING__ |
|
6286 /** |
|
6287 ReadPaged() - |
|
6288 |
|
6289 Sends a paging read request to the specified attached drive |
|
6290 |
|
6291 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6292 media, not the partition |
|
6293 */ |
|
6294 EXPORT_C TInt DMediaDriverExtension::ReadPaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6295 { |
|
6296 return SendRequest(DLocalDrive::ERead, ETrue, aDriveNumber, aPos, aData, aLen); |
|
6297 } |
|
6298 |
|
6299 /** |
|
6300 WritePaged() - |
|
6301 |
|
6302 Send a paging write request to the specified attached drive |
|
6303 |
|
6304 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6305 media, not the partition |
|
6306 */ |
|
6307 EXPORT_C TInt DMediaDriverExtension::WritePaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen) |
|
6308 { |
|
6309 return SendRequest(DLocalDrive::EWrite, ETrue, aDriveNumber, aPos, aData, aLen); |
|
6310 } |
|
6311 #endif // __DEMAND_PAGING__ |
|
6312 |
|
6313 |
|
6314 |
|
6315 /** |
|
6316 Caps() - |
|
6317 |
|
6318 gets the caps from the next attached drive in the chain |
|
6319 |
|
6320 N.B. The position is assumed to be already adjusted i.e. relative to the start of the |
|
6321 media, not the partition |
|
6322 */ |
|
6323 EXPORT_C TInt DMediaDriverExtension::Caps(TInt aDriveNumber, TDes8& aCaps) |
|
6324 { |
|
6325 // Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice() |
|
6326 if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber))) |
|
6327 return KErrArgument; |
|
6328 |
|
6329 TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia); |
|
6330 __ASSERT_DEBUG(drive, LOCM_FAULT()); |
|
6331 TLocDrv* attachedDrive = drive->iNextDrive; |
|
6332 __ASSERT_DEBUG(attachedDrive, LOCM_FAULT()); |
|
6333 |
|
6334 TLocDrvRequest request; |
|
6335 memclr(&request, sizeof(request)); |
|
6336 |
|
6337 request.Drive() = attachedDrive; |
|
6338 request.Id() = DLocalDrive::ECaps; |
|
6339 request.Length() = aCaps.Length(); |
|
6340 request.RemoteDes() = (TAny*) aCaps.Ptr(); |
|
6341 |
|
6342 return request.SendReceive(&attachedDrive->iPrimaryMedia->iMsgQ); |
|
6343 } |
|
6344 |
|
6345 |
|
6346 |
|
6347 EXPORT_C void DMediaDriverExtension::NotifyPowerDown() |
|
6348 { |
|
6349 } |
|
6350 |
|
6351 EXPORT_C void DMediaDriverExtension::NotifyEmergencyPowerDown() |
|
6352 { |
|
6353 } |
|
6354 |
|
6355 |
|
6356 /** |
|
6357 Returns ETrue if this media - or any media which this TLocDrv is attached to - is busy |
|
6358 */ |
|
6359 EXPORT_C TBool DMediaDriverExtension::MediaBusy(TInt aDriveNumber) |
|
6360 { |
|
6361 for (TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia); |
|
6362 drive; |
|
6363 drive = drive->iNextDrive) |
|
6364 { |
|
6365 DPrimaryMediaBase* primaryMedia = drive->iPrimaryMedia; |
|
6366 __ASSERT_DEBUG(primaryMedia, LOCM_FAULT()); |
|
6367 |
|
6368 if ((primaryMedia->iMsgQ.iMessage && primaryMedia->iMsgQ.iMessage->iState != TMessageBase::EFree) || |
|
6369 !primaryMedia->iMsgQ.iQ.IsEmpty() || |
|
6370 primaryMedia->iBody->iMediaChangeDfc.Queued() || |
|
6371 primaryMedia->iBody->iMediaPresentDfc.Queued()) |
|
6372 return ETrue; |
|
6373 |
|
6374 #ifdef __DEMAND_PAGING__ |
|
6375 DMediaPagingDevice* pagingDevice = iPrimaryMedia->iBody->iPagingDevice; |
|
6376 if (pagingDevice) |
|
6377 { |
|
6378 if ((pagingDevice->iMainQ.iMessage && pagingDevice->iMainQ.iMessage->iState != TMessageBase::EFree) || |
|
6379 !pagingDevice->iMainQ.iQ.IsEmpty()) |
|
6380 return ETrue; |
|
6381 } |
|
6382 #endif |
|
6383 } |
|
6384 |
|
6385 return EFalse; |
|
6386 } |
|
6387 |
|
6388 |
|
6389 TCallBackLink::TCallBackLink() |
|
6390 { |
|
6391 memclr(this, sizeof(this)); |
|
6392 } |
|
6393 |
|
6394 TCallBackLink::TCallBackLink(TInt (*aFunction)(TAny* aPtr, TInt aParam),TAny* aPtr, TObjectType aObjectType) : |
|
6395 iFunction(aFunction), iPtr(aPtr), iObjectType(aObjectType) |
|
6396 { |
|
6397 } |
|
6398 |
|
6399 TInt TCallBackLink::CallBack(TInt aParam) const |
|
6400 { |
|
6401 return (*iFunction)(iPtr, aParam); |
|
6402 } |
|
6403 |
|
6404 /****************************************************************************** |
5740 Entry point |
6405 Entry point |
5741 ******************************************************************************/ |
6406 ******************************************************************************/ |
5742 DECLARE_STANDARD_EXTENSION() |
6407 DECLARE_STANDARD_EXTENSION() |
5743 { |
6408 { |
5744 __KTRACE_OPT(KBOOT,Kern::Printf("Starting LOCMEDIA extension")); |
6409 __KTRACE_OPT(KBOOT,Kern::Printf("Starting LOCMEDIA extension")); |
5745 |
6410 |
5746 // install the HAL function |
6411 // install the HAL function |
5747 TInt r=Kern::AddHalEntry(EHalGroupMedia,MediaHalFunction,NULL); |
6412 TInt r=Kern::AddHalEntry(EHalGroupMedia,MediaHalFunction,NULL); |
|
6413 |
5748 #ifdef __DEMAND_PAGING__ |
6414 #ifdef __DEMAND_PAGING__ |
5749 if (r==KErrNone) |
6415 if (r==KErrNone) |
5750 { |
6416 { |
5751 __KTRACE_OPT(KBOOT,Kern::Printf("Creating LocDrv device")); |
6417 __KTRACE_OPT(KBOOT,Kern::Printf("Creating LocDrv device")); |
5752 DLocalDriveFactory* device = new DLocalDriveFactory; |
6418 DLocalDriveFactory* device = new DLocalDriveFactory; |