121 } |
133 } |
122 } |
134 } |
123 else |
135 else |
124 aEraseInfo.iEraseFlags=0; |
136 aEraseInfo.iEraseFlags=0; |
125 |
137 |
126 return(KErrNone); |
138 OstTraceFunctionExitExt( TSDCARD_GETERASEINFO_EXIT, this, KErrNone ); |
|
139 return KErrNone; |
127 } |
140 } |
128 |
141 |
129 TInt TSDCard::MaxReadBlLen() const |
142 TInt TSDCard::MaxReadBlLen() const |
130 /** |
143 /** |
131 * Returns the maximum read block length supported by the card encoded as a logarithm |
144 * Returns the maximum read block length supported by the card encoded as a logarithm |
132 * Normally this is the same as the READ_BL_LEN field in the CSD register, |
145 * Normally this is the same as the READ_BL_LEN field in the CSD register, |
133 * but for high capacity cards (> 2GB) this is set to a maximum of 512 bytes, |
146 * but for high capacity cards (> 2GB) this is set to a maximum of 512 bytes, |
134 * if possible, to try to avoid compatibility issues. |
147 * if possible, to try to avoid compatibility issues. |
135 */ |
148 */ |
136 { |
149 { |
|
150 OstTraceFunctionEntry1( TSDCARD_MAXREADBLLEN_ENTRY, this ); |
137 if (IsSDCard()) |
151 if (IsSDCard()) |
138 { |
152 { |
139 TInt blkLenLog2 = CSD().ReadBlLen(); |
153 TInt blkLenLog2 = CSD().ReadBlLen(); |
140 if (blkLenLog2 == KTwoGbyteSDBlockLen || blkLenLog2 == KFourGbyteSDBlockLen) |
154 if (blkLenLog2 == KTwoGbyteSDBlockLen || blkLenLog2 == KFourGbyteSDBlockLen) |
141 { |
155 { |
142 // The SD card spec. makes a special case for 2GByte cards, |
156 // The SD card spec. makes a special case for 2GByte cards, |
143 // ...and some manufacturers apply the same method to support 4G cards |
157 // ...and some manufacturers apply the same method to support 4G cards |
144 __KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl > 2GB SD")); |
158 __KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl > 2GB SD")); |
|
159 OstTrace0( TRACE_INTERNALS, TSDCARD_MAXREADBLLEN, "SD Card > 2GB" ); |
145 blkLenLog2 = KDefaultBlockLen; |
160 blkLenLog2 = KDefaultBlockLen; |
146 } |
161 } |
|
162 OstTraceFunctionExitExt( TSDCARD_MAXREADBLLEN_EXIT, this, blkLenLog2 ); |
147 return blkLenLog2; |
163 return blkLenLog2; |
148 } |
164 } |
149 else // MMC card |
165 else // MMC card |
150 { |
166 { |
151 return (TMMCard::MaxReadBlLen()); |
167 TInt ret = TMMCard::MaxReadBlLen(); |
|
168 OstTraceFunctionExitExt( DUP1_TSDCARD_MAXREADBLLEN_EXIT, this, ret ); |
|
169 return ret; |
152 } |
170 } |
153 } |
171 } |
154 |
172 |
155 TInt TSDCard::MaxWriteBlLen() const |
173 TInt TSDCard::MaxWriteBlLen() const |
156 /** |
174 /** |
158 * Normally this is the same as the WRITE_BL_LEN field in the CSD register, |
176 * Normally this is the same as the WRITE_BL_LEN field in the CSD register, |
159 * but for high capacity cards (> 2GB) this is set to a maximum of 512 bytes, |
177 * but for high capacity cards (> 2GB) this is set to a maximum of 512 bytes, |
160 * if possible, to try to avoid compatibility issues. |
178 * if possible, to try to avoid compatibility issues. |
161 */ |
179 */ |
162 { |
180 { |
|
181 OstTraceFunctionEntry1( TSDCARD_MAXWRITEBLLEN_ENTRY, this ); |
163 if (IsSDCard()) |
182 if (IsSDCard()) |
164 { |
183 { |
165 TInt blkLenLog2 = CSD().WriteBlLen(); |
184 TInt blkLenLog2 = CSD().WriteBlLen(); |
166 if (blkLenLog2 == KTwoGbyteSDBlockLen || blkLenLog2 == KFourGbyteSDBlockLen) |
185 if (blkLenLog2 == KTwoGbyteSDBlockLen || blkLenLog2 == KFourGbyteSDBlockLen) |
167 { |
186 { |
168 // The SD card spec. makes a special case for 2GByte cards, |
187 // The SD card spec. makes a special case for 2GByte cards, |
169 // ...and some manufacturers apply the same method to support 4G cards |
188 // ...and some manufacturers apply the same method to support 4G cards |
170 __KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mwbl > 2GB SD")); |
189 __KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mwbl > 2GB SD")); |
|
190 OstTrace0( TRACE_INTERNALS, TSDCARD_MAXWRITEBLLEN, "SD Card > 2GB" ); |
171 blkLenLog2 = KDefaultBlockLen; |
191 blkLenLog2 = KDefaultBlockLen; |
172 } |
192 } |
|
193 OstTraceFunctionExitExt( TSDCARD_MAXWRITEBLLEN_EXIT, this, blkLenLog2 ); |
173 return blkLenLog2; |
194 return blkLenLog2; |
174 } |
195 } |
175 else // MMC card |
196 else // MMC card |
176 { |
197 { |
177 return (TMMCard::MaxWriteBlLen()); |
198 TInt ret = TMMCard::MaxWriteBlLen(); |
|
199 OstTraceFunctionExitExt( DUP1_TSDCARD_MAXWRITEBLLEN_EXIT, this, ret ); |
|
200 return ret; |
178 } |
201 } |
179 } |
202 } |
180 |
203 |
181 TUint TSDCard::MaxTranSpeedInKilohertz() const |
204 TUint TSDCard::MaxTranSpeedInKilohertz() const |
182 /** |
205 /** |
183 * Returns the maximum supported clock rate for the card, in Kilohertz. |
206 * Returns the maximum supported clock rate for the card, in Kilohertz. |
184 * @return Speed, in Kilohertz |
207 * @return Speed, in Kilohertz |
185 */ |
208 */ |
186 { |
209 { |
|
210 OstTraceFunctionEntry1( TSDCARD_MAXTRANSPEEDINKILOHERTZ_ENTRY, this ); |
187 TUint maxClk = TMMCard::MaxTranSpeedInKilohertz(); |
211 TUint maxClk = TMMCard::MaxTranSpeedInKilohertz(); |
188 |
212 |
189 if (IsSDCard()) |
213 if (IsSDCard()) |
190 { |
214 { |
191 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >TSDCard(%d): MaxTranSpeedInKilohertz: %d",(iIndex-1),maxClk)); |
215 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >TSDCard(%d): MaxTranSpeedInKilohertz: %d",(iIndex-1),maxClk)); |
215 // allocate TSDCard objects for iCards and iNewCardsArray. This function |
242 // allocate TSDCard objects for iCards and iNewCardsArray. This function |
216 // is called at bootup as part of stack allocation so there is no cleanup |
243 // is called at bootup as part of stack allocation so there is no cleanup |
217 // if it fails. |
244 // if it fails. |
218 // |
245 // |
219 { |
246 { |
|
247 OstTraceFunctionEntry1( TSDCARDARRAY_ALLOCCARDS_ENTRY, this ); |
220 for (TInt i = 0; i < (TInt) KMaxMMCardsPerStack; ++i) |
248 for (TInt i = 0; i < (TInt) KMaxMMCardsPerStack; ++i) |
221 { |
249 { |
222 // zeroing the card data used to be implicit because embedded in |
250 // zeroing the card data used to be implicit because embedded in |
223 // CBase-derived DMMCStack. |
251 // CBase-derived DMMCStack. |
224 if ((iCards[i] = new TSDCard) == 0) |
252 if ((iCards[i] = new TSDCard) == 0) |
|
253 { |
|
254 OstTraceFunctionExitExt( TSDCARDARRAY_ALLOCCARDS_EXIT, this, KErrNoMemory ); |
225 return KErrNoMemory; |
255 return KErrNoMemory; |
|
256 } |
226 iCards[i]->iUsingSessionP = 0; |
257 iCards[i]->iUsingSessionP = 0; |
227 if ((iNewCards[i] = new TSDCard) == 0) |
258 if ((iNewCards[i] = new TSDCard) == 0) |
|
259 { |
|
260 OstTraceFunctionExitExt( DUP1_TSDCARDARRAY_ALLOCCARDS_EXIT, this, KErrNoMemory ); |
228 return KErrNoMemory; |
261 return KErrNoMemory; |
|
262 } |
229 } |
263 } |
230 |
264 |
|
265 OstTraceFunctionExitExt( DUP2_TSDCARDARRAY_ALLOCCARDS_EXIT, this, KErrNone ); |
231 return KErrNone; |
266 return KErrNone; |
232 } |
267 } |
233 |
268 |
234 void TSDCardArray::AddCardSDMode(TUint aCardNumber,const TUint8* aCID,TRCA* aNewRCA) |
269 void TSDCardArray::AddCardSDMode(TUint aCardNumber,const TUint8* aCID,TRCA* aNewRCA) |
235 // |
270 // |
236 // Add an MMC card straight to the main card array in slot 'aCardNumber'. Save |
271 // Add an MMC card straight to the main card array in slot 'aCardNumber'. Save |
237 // the CID value in the slot. Return a RCA for the card. |
272 // the CID value in the slot. Return a RCA for the card. |
238 // |
273 // |
239 { |
274 { |
|
275 OstTraceFunctionEntryExt( TSDCARDARRAY_ADDCARDSDMODE_ENTRY, this ); |
240 |
276 |
241 TRCA rca=0; |
277 TRCA rca=0; |
242 |
278 |
243 // First, lets check if the same card was here before. If it was, keep the same RCA |
279 // First, lets check if the same card was here before. If it was, keep the same RCA |
244 if (Card(aCardNumber).IsPresent() && Card(aCardNumber).iCID==aCID) |
280 if (Card(aCardNumber).IsPresent() && Card(aCardNumber).iCID==aCID) |
254 iOwningStack->iRCAPool.LockRCA(Card(aCardNumber).iRCA); |
290 iOwningStack->iRCAPool.LockRCA(Card(aCardNumber).iRCA); |
255 } |
291 } |
256 |
292 |
257 Card(aCardNumber).iIndex=(aCardNumber+1); // Mark card as being present |
293 Card(aCardNumber).iIndex=(aCardNumber+1); // Mark card as being present |
258 *aNewRCA=rca; |
294 *aNewRCA=rca; |
|
295 OstTraceFunctionExit1( TSDCARDARRAY_ADDCARDSDMODE_EXIT, this ); |
259 } |
296 } |
260 |
297 |
261 TInt TSDCardArray::StoreRCAIfUnique(TUint aCardNumber,TRCA& anRCA) |
298 TInt TSDCardArray::StoreRCAIfUnique(TUint aCardNumber,TRCA& anRCA) |
262 // |
299 // |
263 // Check that no other array element has the same RCA value 'anRCA'. If no |
300 // Check that no other array element has the same RCA value 'anRCA'. If no |
264 // no duplication then store in slot 'aCardNumber'. |
301 // no duplication then store in slot 'aCardNumber'. |
265 // |
302 // |
266 { |
303 { |
|
304 OstTraceExt3(TRACE_FLOW, TSDCARDARRAY_STORERCAIFUNIQUE_ENTRY ,"TSDCardArray::StoreRCAIfUnique;aCardNumber=%x;anRCA=%x;this=%x", aCardNumber, (TUint) anRCA, (TUint) this); |
267 |
305 |
268 if (anRCA==0) |
306 if (anRCA==0) |
269 return(KErrGeneral); |
307 { |
|
308 OstTraceFunctionExitExt( TSDCARDARRAY_STORERCAIFUNIQUE_EXIT, this, KErrGeneral ); |
|
309 return KErrGeneral; |
|
310 } |
270 Card(aCardNumber).iRCA=0; |
311 Card(aCardNumber).iRCA=0; |
271 |
312 |
272 // Now let's look if we've seen this card before |
313 // Now let's look if we've seen this card before |
273 for ( TUint i=0 ; i<iOwningStack->iMaxCardsInStack ; i++ ) |
314 for ( TUint i=0 ; i<iOwningStack->iMaxCardsInStack ; i++ ) |
274 { |
315 { |
275 if ( Card(i).IsPresent() && Card(i).iRCA==anRCA ) |
316 if ( Card(i).IsPresent() && Card(i).iRCA==anRCA ) |
276 return(KErrInUse); |
317 { |
|
318 OstTraceFunctionExitExt( DUP1_TSDCARDARRAY_STORERCAIFUNIQUE_EXIT, this, KErrInUse ); |
|
319 return KErrInUse; |
|
320 } |
277 } |
321 } |
278 Card(aCardNumber).iRCA=anRCA; |
322 Card(aCardNumber).iRCA=anRCA; |
279 Card(aCardNumber).iIndex=(aCardNumber+1); // Mark card as being present |
323 Card(aCardNumber).iIndex=(aCardNumber+1); // Mark card as being present |
280 return(KErrNone); |
324 OstTraceFunctionExitExt( DUP2_TSDCARDARRAY_STORERCAIFUNIQUE_EXIT, this, KErrNone ); |
|
325 return KErrNone; |
281 } |
326 } |
282 |
327 |
283 EXPORT_C void TSDCardArray::DeclareCardAsGone(TUint aCardNumber) |
328 EXPORT_C void TSDCardArray::DeclareCardAsGone(TUint aCardNumber) |
284 // |
329 // |
285 // reset SD specific fields to initial values and then reset generic MultiMediaCard |
330 // reset SD specific fields to initial values and then reset generic MultiMediaCard |
286 // |
331 // |
287 { |
332 { |
|
333 OstTraceFunctionEntryExt( TSDCARDARRAY_DECLARECARDASGONE_ENTRY, this ); |
288 Card(aCardNumber).SetBusWidth(1); |
334 Card(aCardNumber).SetBusWidth(1); |
289 TMMCardArray::DeclareCardAsGone(aCardNumber); |
335 TMMCardArray::DeclareCardAsGone(aCardNumber); |
|
336 OstTraceFunctionExit1( TSDCARDARRAY_DECLARECARDASGONE_EXIT, this ); |
290 } |
337 } |
291 |
338 |
292 // ======== DSDSession ======== |
339 // ======== DSDSession ======== |
293 |
340 |
294 void DSDSession::FillAppCommandDesc(TMMCCommandDesc& aDesc, TSDAppCmd aCmd) |
341 void DSDSession::FillAppCommandDesc(TMMCCommandDesc& aDesc, TSDAppCmd aCmd) |
295 { |
342 { |
|
343 OstTraceFunctionEntry0( DSDSESSION_FILLAPPCOMMANDDESC_ENTRY ); |
296 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
344 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
297 aDesc.iArgument = 0; // set stuff bits to zero |
345 aDesc.iArgument = 0; // set stuff bits to zero |
298 FillAppCommandDesc(aDesc); |
346 FillAppCommandDesc(aDesc); |
|
347 OstTraceFunctionExit0( DSDSESSION_FILLAPPCOMMANDDESC_EXIT ); |
299 } |
348 } |
300 |
349 |
301 void DSDSession::FillAppCommandDesc(TMMCCommandDesc& aDesc, TSDAppCmd aCmd, TMMCArgument aArg) |
350 void DSDSession::FillAppCommandDesc(TMMCCommandDesc& aDesc, TSDAppCmd aCmd, TMMCArgument aArg) |
302 { |
351 { |
|
352 OstTraceFunctionEntry0( DUP1_DSDSESSION_FILLAPPCOMMANDDESC_ENTRY ); |
303 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
353 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
304 aDesc.iArgument = aArg; |
354 aDesc.iArgument = aArg; |
305 FillAppCommandDesc(aDesc); |
355 FillAppCommandDesc(aDesc); |
|
356 OstTraceFunctionExit0( DUP1_DSDSESSION_FILLAPPCOMMANDDESC_EXIT ); |
306 } |
357 } |
307 |
358 |
308 const TUint32 CCA = KMMCCmdClassApplication; |
359 const TUint32 CCA = KMMCCmdClassApplication; |
309 const TMMCIdxCommandSpec AppCmdSpecTable[] = |
360 const TMMCIdxCommandSpec AppCmdSpecTable[] = |
310 { // Class Type Dir MBlk StopT Rsp Type Len |
361 { // Class Type Dir MBlk StopT Rsp Type Len |
338 {ESDCmdSendIfCond, {KMMCCmdClassBasic, ECmdTypeBCR, EDirNone, EFalse, EFalse, ERespTypeR7, 4}} // CMD8 : SEND_IF_COND |
391 {ESDCmdSendIfCond, {KMMCCmdClassBasic, ECmdTypeBCR, EDirNone, EFalse, EFalse, ERespTypeR7, 4}} // CMD8 : SEND_IF_COND |
339 }; |
392 }; |
340 |
393 |
341 void DSDSession::FillSdSpecificCommandDesc(TMMCCommandDesc& aDesc, TSDSpecificCmd aCmd, TMMCArgument aArg) |
394 void DSDSession::FillSdSpecificCommandDesc(TMMCCommandDesc& aDesc, TSDSpecificCmd aCmd, TMMCArgument aArg) |
342 { |
395 { |
|
396 OstTraceFunctionEntry0( DSDSESSION_FILLSDSPECIFICCOMMANDDESC_ENTRY ); |
343 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
397 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
344 aDesc.iArgument = aArg; |
398 aDesc.iArgument = aArg; |
345 FillSdSpecificCommandDesc(aDesc); |
399 FillSdSpecificCommandDesc(aDesc); |
|
400 OstTraceFunctionExit0( DSDSESSION_FILLSDSPECIFICCOMMANDDESC_EXIT ); |
346 } |
401 } |
347 |
402 |
348 void DSDSession::FillSdSpecificCommandDesc(TMMCCommandDesc& aDesc, TSDSpecificCmd aCmd) |
403 void DSDSession::FillSdSpecificCommandDesc(TMMCCommandDesc& aDesc, TSDSpecificCmd aCmd) |
349 { |
404 { |
|
405 OstTraceFunctionEntry0( DUP1_DSDSESSION_FILLSDSPECIFICCOMMANDDESC_ENTRY ); |
350 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
406 aDesc.iCommand = (TMMCCommandEnum) aCmd; |
351 aDesc.iArgument = 0; // set stuff bits to zero |
407 aDesc.iArgument = 0; // set stuff bits to zero |
352 FillSdSpecificCommandDesc(aDesc); |
408 FillSdSpecificCommandDesc(aDesc); |
|
409 OstTraceFunctionExit0( DUP1_DSDSESSION_FILLSDSPECIFICCOMMANDDESC_EXIT ); |
353 } |
410 } |
354 |
411 |
355 void DSDSession::FillSdSpecificCommandDesc(TMMCCommandDesc& aDesc) |
412 void DSDSession::FillSdSpecificCommandDesc(TMMCCommandDesc& aDesc) |
356 { |
413 { |
|
414 OstTraceFunctionEntry0( DUP2_DSDSESSION_FILLSDSPECIFICCOMMANDDESC_ENTRY ); |
357 aDesc.iSpec = FindCommandSpec(SdSpecificCmdSpecTable, aDesc.iCommand); |
415 aDesc.iSpec = FindCommandSpec(SdSpecificCmdSpecTable, aDesc.iCommand); |
358 aDesc.iFlags = 0; |
416 aDesc.iFlags = 0; |
359 aDesc.iBytesDone = 0; |
417 aDesc.iBytesDone = 0; |
|
418 OstTraceFunctionExit0( DUP2_DSDSESSION_FILLSDSPECIFICCOMMANDDESC_EXIT ); |
360 } |
419 } |
361 |
420 |
362 |
421 |
363 // ======== DSDStack ======== |
422 // ======== DSDStack ======== |
364 |
423 |
365 EXPORT_C TInt DSDStack::Init() |
424 EXPORT_C TInt DSDStack::Init() |
366 { |
425 { |
367 return DMMCStack::Init(); |
426 OstTraceFunctionEntry1( DSDSTACK_INIT_ENTRY, this ); |
|
427 TInt ret = DMMCStack::Init(); |
|
428 OstTraceFunctionExitExt( DSDSTACK_INIT_EXIT, this, ret ); |
|
429 return ret; |
368 } |
430 } |
369 |
431 |
370 |
432 |
371 const TInt KMaxRCASendLoops=3; |
433 const TInt KMaxRCASendLoops=3; |
372 const TUint KSDMaxPollAttempts=25; |
434 const TUint KSDMaxPollAttempts=25; |
455 SMF_GOTOS(EStMoreCardsCheck) // Timed out, try the next card slot |
521 SMF_GOTOS(EStMoreCardsCheck) // Timed out, try the next card slot |
456 } |
522 } |
457 |
523 |
458 SMF_STATE(EStIssueSendRCA) |
524 SMF_STATE(EStIssueSendRCA) |
459 |
525 |
|
526 OstTrace0( TRACE_INTERNALS, DSDSTACK_ATTACHCARDSM4, "EStIssueSendRCA" ); |
460 SMF_INVOKES(ExecCommandSMST,EStSendRCACheck) |
527 SMF_INVOKES(ExecCommandSMST,EStSendRCACheck) |
461 |
528 |
462 SMF_STATE(EStSendRCACheck) |
529 SMF_STATE(EStSendRCACheck) |
463 |
530 |
|
531 OstTrace0( TRACE_INTERNALS, DSDSTACK_ATTACHCARDSM5, "EStSendRCACheck" ); |
464 // We need to check that the RCA recieved from the card doesn't clash |
532 // We need to check that the RCA recieved from the card doesn't clash |
465 // with any others in this stack. RCA is first 2 bytes of response buffer (in big endian) |
533 // with any others in this stack. RCA is first 2 bytes of response buffer (in big endian) |
466 TRCA rca=(TUint16)((s.ResponseP()[0]<<8) | s.ResponseP()[1]); |
534 TRCA rca=(TUint16)((s.ResponseP()[0]<<8) | s.ResponseP()[1]); |
467 if (CardArray().StoreRCAIfUnique(iCxCardCount,rca)!=KErrNone) |
535 if (CardArray().StoreRCAIfUnique(iCxCardCount,rca)!=KErrNone) |
468 SMF_GOTOS( ((++iCxPollRetryCount<KMaxRCASendLoops)?EStIssueSendRCA:EStMoreCardsCheck) ) |
536 SMF_GOTOS( ((++iCxPollRetryCount<KMaxRCASendLoops)?EStIssueSendRCA:EStMoreCardsCheck) ) |
469 |
537 |
470 SMF_STATE(EStRCADone) |
538 SMF_STATE(EStRCADone) |
471 |
539 |
|
540 OstTrace0( TRACE_INTERNALS, DSDSTACK_ATTACHCARDSM6, "EStRCADone" ); |
472 SMF_INVOKES(ConfigureMemoryCardSMST, EStMoreCardsCheck) |
541 SMF_INVOKES(ConfigureMemoryCardSMST, EStMoreCardsCheck) |
473 |
542 |
474 SMF_STATE(EStMoreCardsCheck) |
543 SMF_STATE(EStMoreCardsCheck) |
475 |
544 |
|
545 OstTrace0( TRACE_INTERNALS, DSDSTACK_ATTACHCARDSM7, "EStMoreCardsCheck" ); |
476 if (++iCxCardCount < (TInt)iMaxCardsInStack) |
546 if (++iCxCardCount < (TInt)iMaxCardsInStack) |
477 { |
547 { |
478 __KTRACE_OPT(KPBUS1, Kern::Printf(">DSDStack::AcquireStackSM(): More Cards to check: %d",iCxCardCount)); |
548 __KTRACE_OPT(KPBUS1, Kern::Printf(">DSDStack::AcquireStackSM(): More Cards to check: %d",iCxCardCount)); |
|
549 OstTrace1( TRACE_INTERNALS, DSDSTACK_ACQUIRESTACKSM8, "More Cards to check: iCxCardCount=%d", iCxCardCount ); |
479 SMF_GOTOS(EStNextFullRange) |
550 SMF_GOTOS(EStNextFullRange) |
480 } |
551 } |
481 else |
552 else |
482 { |
553 { |
483 AddressCard(KBroadcastToAllCards); // Set back to broadcast mode |
554 AddressCard(KBroadcastToAllCards); // Set back to broadcast mode |
514 EStEnd |
585 EStEnd |
515 }; |
586 }; |
516 |
587 |
517 DMMCSession& s=Session(); |
588 DMMCSession& s=Session(); |
518 DMMCPsu* psu=(DMMCPsu*)MMCSocket()->iVcc; |
589 DMMCPsu* psu=(DMMCPsu*)MMCSocket()->iVcc; |
|
590 OstTrace1( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM, "Current session = 0x%x", &s ); |
519 |
591 |
520 static const TUint32 KCmd8Param = 0x0100 | 0x00AA; // Voltage supplied : 2.7-3.6V, Check Pattern 10101010b |
592 static const TUint32 KCmd8Param = 0x0100 | 0x00AA; // Voltage supplied : 2.7-3.6V, Check Pattern 10101010b |
521 static const TUint32 KCmd8CheckMask = 0x00000FFF; |
593 static const TUint32 KCmd8CheckMask = 0x00000FFF; |
522 |
594 |
523 SMF_BEGIN |
595 SMF_BEGIN |
524 |
596 |
|
597 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM1, "EStBegin" ); |
525 iCxCardType = ESDCardTypeUnknown; |
598 iCxCardType = ESDCardTypeUnknown; |
526 s.iCardP = NULL; // This stops ExecCommandSM() from setting old RCA when sending CMD55 |
599 s.iCardP = NULL; // This stops ExecCommandSM() from setting old RCA when sending CMD55 |
527 |
600 |
528 // Send CMD0 to initialise memory |
601 // Send CMD0 to initialise memory |
529 SMF_INVOKES(GoIdleSMST, EStSendInterfaceCondition); |
602 SMF_INVOKES(GoIdleSMST, EStSendInterfaceCondition); |
530 |
603 |
531 SMF_STATE(EStSendInterfaceCondition) |
604 SMF_STATE(EStSendInterfaceCondition) |
532 |
605 |
|
606 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM2, "EStSendInterfaceCondition" ); |
533 iCxPollRetryCount=0; // Reset max number of poll attempts on card busy |
607 iCxPollRetryCount=0; // Reset max number of poll attempts on card busy |
534 iConfig.SetPollAttempts(KSDMaxPollAttempts); // Increase card busy timeout to 1 Sec for SD Cards |
608 iConfig.SetPollAttempts(KSDMaxPollAttempts); // Increase card busy timeout to 1 Sec for SD Cards |
535 |
609 |
536 iConfig.RemoveMode( KMMCModeEnableTimeOutRetry ); // Temporarily disable timeout retries - since we use a timeout event to distinguish between MMC and SD |
610 iConfig.RemoveMode( KMMCModeEnableTimeOutRetry ); // Temporarily disable timeout retries - since we use a timeout event to distinguish between MMC and SD |
537 |
611 |
540 // SD2.0 defines CMD8 as having a new response type - R7 |
614 // SD2.0 defines CMD8 as having a new response type - R7 |
541 // if the PSL doesn't indicate support for R7, use R1 instead |
615 // if the PSL doesn't indicate support for R7, use R1 instead |
542 if (!(MMCSocket()->MachineInfo().iFlags & TMMCMachineInfo::ESupportsR7)) |
616 if (!(MMCSocket()->MachineInfo().iFlags & TMMCMachineInfo::ESupportsR7)) |
543 { |
617 { |
544 __KTRACE_OPT(KPBUS1, Kern::Printf("R7 not supported.")); |
618 __KTRACE_OPT(KPBUS1, Kern::Printf("R7 not supported.")); |
|
619 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM3, "R7 not supported" ); |
545 Command().iSpec.iResponseType = ERespTypeR1; |
620 Command().iSpec.iResponseType = ERespTypeR1; |
546 } |
621 } |
547 |
622 |
548 |
623 |
549 m.SetTraps(KMMCErrAll); |
624 m.SetTraps(KMMCErrAll); |
550 SMF_INVOKES(ExecCommandSMST, EStSentInterfaceCondition) |
625 SMF_INVOKES(ExecCommandSMST, EStSentInterfaceCondition) |
551 |
626 |
552 SMF_STATE(EStSentInterfaceCondition) |
627 SMF_STATE(EStSentInterfaceCondition) |
553 |
628 |
|
629 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM4, "EStSentInterfaceCondition" ); |
554 if (err == KMMCErrNone) |
630 if (err == KMMCErrNone) |
555 { |
631 { |
556 // Check the response for voltage and check pattern |
632 // Check the response for voltage and check pattern |
557 const TUint32 status = TMMC::BigEndian32(s.ResponseP()); |
633 const TUint32 status = TMMC::BigEndian32(s.ResponseP()); |
558 if((status & KCmd8CheckMask) == KCmd8Param) |
634 if((status & KCmd8CheckMask) == KCmd8Param) |
559 { |
635 { |
560 __KTRACE_OPT(KPBUS1, Kern::Printf("Found v2 card.")); |
636 __KTRACE_OPT(KPBUS1, Kern::Printf("Found v2 card.")); |
|
637 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM5, "Found v2 card" ); |
561 iCurrentOpRange |= KMMCOCRAccessModeHCS; |
638 iCurrentOpRange |= KMMCOCRAccessModeHCS; |
562 } |
639 } |
563 else |
640 else |
564 { |
641 { |
565 // Pattern Mis-match, card does not support the specified voltage range |
642 // Pattern Mis-match, card does not support the specified voltage range |
566 return( KMMCErrNotSupported ); |
643 OstTraceFunctionExitExt( DSDSTACK_INITIALISEMEMORYCARDSM_EXIT, this, (TInt) KMMCErrNotSupported ); |
|
644 return KMMCErrNotSupported; |
567 } |
645 } |
568 |
646 |
569 SMF_GOTOS(EStCheckVoltage); |
647 SMF_GOTOS(EStCheckVoltage); |
570 } |
648 } |
571 |
649 |
694 { |
780 { |
695 // No response timeout - so it must be an SD Card |
781 // No response timeout - so it must be an SD Card |
696 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:crct2:%x", iCardArray)); |
782 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:crct2:%x", iCardArray)); |
697 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:crct3:%x", iCxCardCount)); |
783 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:crct3:%x", iCxCardCount)); |
698 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:crct4:%x", CardArray().CardP(iCxCardCount))); |
784 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:crct4:%x", CardArray().CardP(iCxCardCount))); |
|
785 OstTraceExt3(TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM14, "iCardArray=0x%x;iCxCardCount=%d;CardArray().CardP(iCxCardCount)=%d", (TUint) iCardArray, (TInt) iCxCardCount, (TInt) CardArray().CardP(iCxCardCount)); |
699 |
786 |
700 (CardArray().CardP(iCxCardCount)->iFlags)|=KSDCardIsSDCard; |
787 (CardArray().CardP(iCxCardCount)->iFlags)|=KSDCardIsSDCard; |
701 iCxCardType=ESDCardTypeIsSD; |
788 iCxCardType=ESDCardTypeIsSD; |
702 } |
789 } |
703 |
790 |
704 SMF_STATE(EStSetRangeBusyCheck) |
791 SMF_STATE(EStSetRangeBusyCheck) |
705 |
792 |
|
793 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM15, "EStSetRangeBusyCheck" ); |
706 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:src:%d",iCxCardType)); // 1:MMC, 2:SD |
794 __KTRACE_OPT(KPBUS1, Kern::Printf("-mst:ascs:src:%d",iCxCardType)); // 1:MMC, 2:SD |
|
795 OstTrace1( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM16, "iCxCardType=%d", iCxCardType); |
707 |
796 |
708 if ( !err ) |
797 if ( !err ) |
709 { |
798 { |
710 const TUint32 ocrResponse = TMMC::BigEndian32(s.ResponseP()); |
799 const TUint32 ocrResponse = TMMC::BigEndian32(s.ResponseP()); |
711 |
800 |
883 SMF_INVOKES( DMMCStack::InitCurrentCardAfterUnlockSMST, EStMoreCardsCheck ) |
984 SMF_INVOKES( DMMCStack::InitCurrentCardAfterUnlockSMST, EStMoreCardsCheck ) |
884 } |
985 } |
885 |
986 |
886 SMF_STATE(EStSelectCard) |
987 SMF_STATE(EStSelectCard) |
887 |
988 |
|
989 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM3, "EStSelectCard" ); |
888 TRCA targetRCA = CardArray().Card(iCxCardCount).RCA(); |
990 TRCA targetRCA = CardArray().Card(iCxCardCount).RCA(); |
889 if (targetRCA == SelectedCard()) |
991 if (targetRCA == SelectedCard()) |
890 { |
992 { |
891 SMF_GOTOS(EStSetBusWidth) |
993 SMF_GOTOS(EStSetBusWidth) |
892 } |
994 } |
893 |
995 |
894 s.FillCommandDesc(ECmdSelectCard, targetRCA); |
996 s.FillCommandDesc(ECmdSelectCard, targetRCA); |
895 SMF_INVOKES(ExecCommandSMST,EStSetBusWidth) |
997 SMF_INVOKES(ExecCommandSMST,EStSetBusWidth) |
896 |
998 |
897 SMF_STATE(EStSetBusWidth) |
999 SMF_STATE(EStSetBusWidth) |
|
1000 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM4, "EStSetBusWidth" ); |
898 const TMMCStatus status = s.LastStatus(); |
1001 const TMMCStatus status = s.LastStatus(); |
899 if((status & KMMCStatCardIsLocked) != 0) |
1002 if((status & KMMCStatCardIsLocked) != 0) |
900 SMF_GOTOS(EStDeselectCard) |
1003 SMF_GOTOS(EStDeselectCard) |
901 |
1004 |
902 // set bus width with ACMD6 |
1005 // set bus width with ACMD6 |
903 TUint32 arg = TUint32(CardArray().Card(iCxCardCount).RCA()) << 16; |
1006 TUint32 arg = TUint32(CardArray().Card(iCxCardCount).RCA()) << 16; |
904 s.FillCommandDesc(ECmdAppCmd, arg); |
1007 s.FillCommandDesc(ECmdAppCmd, arg); |
905 SMF_INVOKES(IssueCommandCheckResponseSMST,EStSetBusWidth1) |
1008 SMF_INVOKES(IssueCommandCheckResponseSMST,EStSetBusWidth1) |
906 |
1009 |
907 SMF_STATE(EStSetBusWidth1) |
1010 SMF_STATE(EStSetBusWidth1) |
|
1011 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM5, "EStSetBusWidth1" ); |
908 CardArray().Card(iCxCardCount).SetBusWidth(4); |
1012 CardArray().Card(iCxCardCount).SetBusWidth(4); |
909 DSDSession::FillAppCommandDesc(Command(), ESDACmdSetBusWidth, KSDBusWidth4); |
1013 DSDSession::FillAppCommandDesc(Command(), ESDACmdSetBusWidth, KSDBusWidth4); |
910 SMF_INVOKES(IssueCommandCheckResponseSMST,EStGetSDStatus) |
1014 SMF_INVOKES(IssueCommandCheckResponseSMST,EStGetSDStatus) |
911 |
1015 |
912 SMF_STATE(EStGetSDStatus) |
1016 SMF_STATE(EStGetSDStatus) |
|
1017 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM6, "EStGetSDStatus" ); |
913 // Now we have sent ACMD6, ask the controller to set the bus width to 4 |
1018 // Now we have sent ACMD6, ask the controller to set the bus width to 4 |
914 DoSetBusWidth(EBusWidth4); |
1019 DoSetBusWidth(EBusWidth4); |
915 |
1020 |
916 // get protected area size with ACMD13 |
1021 // get protected area size with ACMD13 |
917 TUint32 arg = TUint32(CardArray().Card(iCxCardCount).RCA()) << 16; |
1022 TUint32 arg = TUint32(CardArray().Card(iCxCardCount).RCA()) << 16; |
918 s.FillCommandDesc(ECmdAppCmd,arg); |
1023 s.FillCommandDesc(ECmdAppCmd,arg); |
919 SMF_INVOKES(IssueCommandCheckResponseSMST,EStGetSDStatus1) |
1024 SMF_INVOKES(IssueCommandCheckResponseSMST,EStGetSDStatus1) |
920 |
1025 |
921 SMF_STATE(EStGetSDStatus1) |
1026 SMF_STATE(EStGetSDStatus1) |
|
1027 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM7, "EStGetSDStatus1" ); |
922 DSDSession::FillAppCommandDesc(Command(), ESDACmdSDStatus); |
1028 DSDSession::FillAppCommandDesc(Command(), ESDACmdSDStatus); |
923 s.FillCommandArgs(0, KSDStatusBlockLength, iPSLBuf, KSDStatusBlockLength); |
1029 s.FillCommandArgs(0, KSDStatusBlockLength, iPSLBuf, KSDStatusBlockLength); |
924 SMF_INVOKES(IssueCommandCheckResponseSMST,EStDecodeSDStatus); |
1030 SMF_INVOKES(IssueCommandCheckResponseSMST,EStDecodeSDStatus); |
925 |
1031 |
926 SMF_STATE(EStDecodeSDStatus) |
1032 SMF_STATE(EStDecodeSDStatus) |
|
1033 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM8, "EStDecodeSDStatus" ); |
927 #ifdef _DEBUG |
1034 #ifdef _DEBUG |
928 for (TUint i = 0; i < KSDStatusBlockLength; ++i) |
1035 for (TUint i = 0; i < KSDStatusBlockLength; ++i) |
929 { |
1036 { |
930 __KTRACE_OPT(KPBUS1, Kern::Printf("SD_STATUS[0x%x] = %x", i, iPSLBuf[i])); |
1037 __KTRACE_OPT(KPBUS1, Kern::Printf("SD_STATUS[0x%x] = %x", i, iPSLBuf[i])); |
|
1038 OstTraceExt2( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM9, "SD_STATUS[0x%x]=0x%x", i, (TUint) iPSLBuf[i]); |
931 } |
1039 } |
932 #endif |
1040 #endif |
933 // bits 495:480 are SD_CARD_TYPE. Check this is 00xxh (x = don't care). |
1041 // bits 495:480 are SD_CARD_TYPE. Check this is 00xxh (x = don't care). |
934 |
1042 |
935 if (iPSLBuf[2] != 0) |
1043 if (iPSLBuf[2] != 0) |
|
1044 { |
|
1045 OstTraceFunctionExitExt( DSDSTACK_INITSTACKAFTERUNLOCKSM_EXIT, this, (TInt) KMMCErrNotSupported ); |
936 return KMMCErrNotSupported; |
1046 return KMMCErrNotSupported; |
|
1047 } |
937 |
1048 |
938 // bits 479:448 contain SIZE_OF_PROTECTED_AREA. |
1049 // bits 479:448 contain SIZE_OF_PROTECTED_AREA. |
939 // (This is bytes 4 to 7 in big-endian format.) |
1050 // (This is bytes 4 to 7 in big-endian format.) |
940 |
1051 |
941 TSDCard& sdc = CardArray().Card(iCxCardCount); |
1052 TSDCard& sdc = CardArray().Card(iCxCardCount); |
942 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack: Card %d", iCxCardCount)); |
1053 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack: Card %d", iCxCardCount)); |
943 TUint32 size_of_protected_area = TMMC::BigEndian32(&iPSLBuf[4]); |
1054 TUint32 size_of_protected_area = TMMC::BigEndian32(&iPSLBuf[4]); |
944 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack: SizeOfProtectedArea: %d", size_of_protected_area)); |
1055 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack: SizeOfProtectedArea: %d", size_of_protected_area)); |
|
1056 OstTraceExt2( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM10, "iCxCardCount=%d;SizeOfProtectedArea=%d", iCxCardCount, (TInt) size_of_protected_area); |
945 const TCSD& csd = sdc.CSD(); |
1057 const TCSD& csd = sdc.CSD(); |
946 TUint32 pas = 0; |
1058 TUint32 pas = 0; |
947 |
1059 |
948 if (sdc.IsHighCapacity()) |
1060 if (sdc.IsHighCapacity()) |
949 { |
1061 { |
950 // High Capacity Card |
1062 // High Capacity Card |
951 // Protected Area = SIZE_OF_PROTECTED_AREA |
1063 // Protected Area = SIZE_OF_PROTECTED_AREA |
952 pas = size_of_protected_area; |
1064 pas = size_of_protected_area; |
953 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack(SDHC): SetProtectedAreaSize: %d", pas)); |
1065 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack(SDHC): SetProtectedAreaSize: %d", pas)); |
|
1066 OstTrace1( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM11, "SDHC: SetProtectedAreaSize=%d", pas); |
954 } |
1067 } |
955 else |
1068 else |
956 { |
1069 { |
957 // Standard Capacity Card |
1070 // Standard Capacity Card |
958 // Protected Area = SIZE_OF_PROTECTED_AREA * C_SIZE_MULT * BLOCK_LEN |
1071 // Protected Area = SIZE_OF_PROTECTED_AREA * C_SIZE_MULT * BLOCK_LEN |
959 pas = size_of_protected_area * (1 << (csd.CSizeMult() + 2 + csd.ReadBlLen())); |
1072 pas = size_of_protected_area * (1 << (csd.CSizeMult() + 2 + csd.ReadBlLen())); |
960 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack(SDSC): SetProtectedAreaSize: %d", pas)); |
1073 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack(SDSC): SetProtectedAreaSize: %d", pas)); |
|
1074 OstTrace1( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM12, "SDSC: SetProtectedAreaSize=%d", pas); |
961 } |
1075 } |
962 |
1076 |
963 sdc.SetProtectedAreaSize(pas); |
1077 sdc.SetProtectedAreaSize(pas); |
964 |
1078 |
965 //bits 431:428 contain AU_SIZE |
1079 //bits 431:428 contain AU_SIZE |
970 sdc.SetAUSize(au); |
1084 sdc.SetAUSize(au); |
971 |
1085 |
972 SMF_INVOKES(SwitchToHighSpeedModeSMST, EStDeselectCard) |
1086 SMF_INVOKES(SwitchToHighSpeedModeSMST, EStDeselectCard) |
973 |
1087 |
974 SMF_STATE(EStDeselectCard) |
1088 SMF_STATE(EStDeselectCard) |
|
1089 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM13, "EStDeselectCard" ); |
975 s.FillCommandDesc(ECmdSelectCard, 0); |
1090 s.FillCommandDesc(ECmdSelectCard, 0); |
976 SMF_INVOKES(ExecCommandSMST, EStCardDeselectedReadCSD) |
1091 SMF_INVOKES(ExecCommandSMST, EStCardDeselectedReadCSD) |
977 |
1092 |
978 SMF_STATE(EStCardDeselectedReadCSD) |
1093 SMF_STATE(EStCardDeselectedReadCSD) |
|
1094 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM14, "EStCardDeselectedReadCSD" ); |
979 // |
1095 // |
980 // Read the card's CSD register (again) |
1096 // Read the card's CSD register (again) |
981 // |
1097 // |
982 // - We re-read the CSD, as the TRAN_SPEED field may have changed due to a switch to HS Mode |
1098 // - We re-read the CSD, as the TRAN_SPEED field may have changed due to a switch to HS Mode |
983 // |
1099 // |
984 TUint32 arg = TUint32(CardArray().Card(iCxCardCount).RCA()) << 16; |
1100 TUint32 arg = TUint32(CardArray().Card(iCxCardCount).RCA()) << 16; |
985 s.FillCommandDesc( ECmdSendCSD, arg ); |
1101 s.FillCommandDesc( ECmdSendCSD, arg ); |
986 SMF_INVOKES(ExecCommandSMST, EStCSDCmdSent) |
1102 SMF_INVOKES(ExecCommandSMST, EStCSDCmdSent) |
987 |
1103 |
988 SMF_STATE(EStCSDCmdSent) |
1104 SMF_STATE(EStCSDCmdSent) |
|
1105 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM15, "EStCSDCmdSent" ); |
989 // |
1106 // |
990 // Store the CSD in the card entry |
1107 // Store the CSD in the card entry |
991 // |
1108 // |
992 TMMCard* cardP = iCardArray->CardP(iCxCardCount); |
1109 TMMCard* cardP = iCardArray->CardP(iCxCardCount); |
993 cardP->iCSD = s.ResponseP(); |
1110 cardP->iCSD = s.ResponseP(); |
994 |
1111 |
995 SMF_STATE(EStMoreCardsCheck) |
1112 SMF_STATE(EStMoreCardsCheck) |
|
1113 OstTrace0( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM16, "EStMoreCardsCheck" ); |
996 if (++iCxCardCount < (TInt)iMaxCardsInStack) |
1114 if (++iCxCardCount < (TInt)iMaxCardsInStack) |
997 { |
1115 { |
998 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack: Address Next card: %d",iCxCardCount)); |
1116 __KTRACE_OPT(KPBUS1, Kern::Printf("\t >DSDStack: Address Next card: %d",iCxCardCount)); |
|
1117 OstTrace1( TRACE_INTERNALS, DSDSTACK_INITSTACKAFTERUNLOCKSM17, "Address Next card=%d", iCxCardCount); |
999 SMF_GOTOS(EStNextCard) |
1118 SMF_GOTOS(EStNextCard) |
1000 } |
1119 } |
1001 else |
1120 else |
1002 { |
1121 { |
1003 AddressCard(KBroadcastToAllCards); |
1122 AddressCard(KBroadcastToAllCards); |
1061 if(s.iSessionID == ECIMWriteBlock || s.iSessionID == ECIMWriteMBlock) |
1182 if(s.iSessionID == ECIMWriteBlock || s.iSessionID == ECIMWriteMBlock) |
1062 { |
1183 { |
1063 // Check that the card supports class 4 (Write) commands |
1184 // Check that the card supports class 4 (Write) commands |
1064 const TUint ccc = s.iCardP->CSD().CCC(); |
1185 const TUint ccc = s.iCardP->CSD().CCC(); |
1065 if(!(ccc & KMMCCmdClassBlockWrite)) |
1186 if(!(ccc & KMMCCmdClassBlockWrite)) |
1066 return( KMMCErrNotSupported ); |
1187 { |
|
1188 OstTraceFunctionExitExt( DSDSTACK_CIMREADWRITEBLOCKSSM_EXIT, this, (TInt) KMMCErrNotSupported ); |
|
1189 return KMMCErrNotSupported; |
|
1190 } |
1067 } |
1191 } |
1068 |
1192 |
1069 Command().iCustomRetries = 0; // MBW retries |
1193 Command().iCustomRetries = 0; // MBW retries |
1070 s.iState |= KMMCSessStateInProgress; |
1194 s.iState |= KMMCSessStateInProgress; |
1071 m.SetTraps(KMMCErrInitContext); |
1195 m.SetTraps(KMMCErrInitContext); |
1072 |
1196 |
1073 SMF_STATE(EStRestart) // NB: ErrBypass is not processed here |
1197 SMF_STATE(EStRestart) // NB: ErrBypass is not processed here |
1074 |
1198 |
|
1199 OstTrace0( TRACE_INTERNALS, DSDSTACK_CIMREADWRITEBLOCKSSM2, "EStRestart" ); |
1075 SMF_CALLMEWR(EStRestart) // Create a recursive call entry to recover from the errors trapped |
1200 SMF_CALLMEWR(EStRestart) // Create a recursive call entry to recover from the errors trapped |
1076 m.SetTraps(KMMCErrStatus); |
1201 m.SetTraps(KMMCErrStatus); |
1077 if (s.Command().iSpec.iCommandClass!=KMMCCmdClassApplication || s.Command().iCommand==ECmdAppCmd ) |
1202 if (s.Command().iSpec.iCommandClass!=KMMCCmdClassApplication || s.Command().iCommand==ECmdAppCmd ) |
1078 { |
1203 { |
1079 s.ResetCommandStack(); |
1204 s.ResetCommandStack(); |
1080 SMF_INVOKES( AttachCardSMST, EStAttached ) // attachment is mandatory here |
1205 SMF_INVOKES( AttachCardSMST, EStAttached ) // attachment is mandatory here |
1081 } |
1206 } |
1082 |
1207 |
1083 SMF_BPOINT(EStAttached) |
1208 SMF_BPOINT(EStAttached) |
1084 |
1209 |
|
1210 OstTrace0( TRACE_INTERNALS, DSDSTACK_CIMREADWRITEBLOCKSSM3, "EStAttached" ); |
1085 TMMCCommandDesc& cmd = s.Command(); |
1211 TMMCCommandDesc& cmd = s.Command(); |
1086 |
1212 |
1087 const TUint32 blockLength = cmd.BlockLength(); |
1213 const TUint32 blockLength = cmd.BlockLength(); |
1088 if((blockLength == 0) || (blockLength > (TUint)KDefaultBlockLenInBytes)) |
1214 if((blockLength == 0) || (blockLength > (TUint)KDefaultBlockLenInBytes)) |
1089 { |
1215 { |
1090 __KTRACE_OPT(KPBUS1,Kern::Printf(">SD:RWBlocksSM err BlockLen:%d",blockLength)); |
1216 __KTRACE_OPT(KPBUS1,Kern::Printf(">SD:RWBlocksSM err BlockLen:%d",blockLength)); |
|
1217 OstTrace1( TRACE_INTERNALS, DSDSTACK_CIMREADWRITEBLOCKSSM4, "blockLength=%d", blockLength ); |
|
1218 OstTraceFunctionExitExt( DSDSTACK_CIMREADWRITEBLOCKSSM_EXIT1, this, (TInt) KMMCErrArgument ); |
1091 return KMMCErrArgument; |
1219 return KMMCErrArgument; |
1092 } |
1220 } |
1093 |
1221 |
1094 if(s.iSessionID == ECIMReadBlock || |
1222 if(s.iSessionID == ECIMReadBlock || |
1095 s.iSessionID == ECIMWriteBlock || |
1223 s.iSessionID == ECIMWriteBlock || |
1181 |
1318 |
1182 SMF_INVOKES( ExecCommandSMST, EStIssued ) |
1319 SMF_INVOKES( ExecCommandSMST, EStIssued ) |
1183 |
1320 |
1184 SMF_STATE(EStIssued) |
1321 SMF_STATE(EStIssued) |
1185 |
1322 |
|
1323 OstTrace0( TRACE_INTERNALS, DSDSTACK_CIMREADWRITEBLOCKSSM7, "EStIssued" ); |
1186 // check state of card after data transfer with CMD13. |
1324 // check state of card after data transfer with CMD13. |
1187 if (s.Command().Direction() != 0) |
1325 if (s.Command().Direction() != 0) |
1188 { |
1326 { |
1189 SMF_GOTOS(EStWaitFinish) |
1327 SMF_GOTOS(EStWaitFinish) |
1190 } |
1328 } |
1191 |
1329 |
1192 SMF_GOTOS(EStRWFinish); |
1330 SMF_GOTOS(EStRWFinish); |
1193 |
1331 |
1194 SMF_STATE(EStWaitFinish) |
1332 SMF_STATE(EStWaitFinish) |
|
1333 OstTrace0( TRACE_INTERNALS, DSDSTACK_CIMREADWRITEBLOCKSSM8, "EStWaitFinish" ); |
1195 // if MBW fail, then recover by rewriting ALL blocks... |
1334 // if MBW fail, then recover by rewriting ALL blocks... |
1196 // (used to recover using ACMD22, but this has been changed |
1335 // (used to recover using ACMD22, but this has been changed |
1197 // as is difficult to test for little gain in efficiency) |
1336 // as is difficult to test for little gain in efficiency) |
1198 if (Command().iCommand == ECmdWriteMultipleBlock && err != 0) |
1337 if (Command().iCommand == ECmdWriteMultipleBlock && err != 0) |
1199 { |
1338 { |
1200 if (Command().iCustomRetries++ >= (TInt) KSDMaxMBWRetries) |
1339 if (Command().iCustomRetries++ >= (TInt) KSDMaxMBWRetries) |
1201 { |
1340 { |
|
1341 OstTraceFunctionExitExt( DSDSTACK_CIMREADWRITEBLOCKSSM_EXIT5, this, (TInt) err ); |
1202 SMF_RETURN(err) |
1342 SMF_RETURN(err) |
1203 } |
1343 } |
1204 |
1344 |
1205 m.Pop(); // remove recursive call to EStRestart |
1345 m.Pop(); // remove recursive call to EStRestart |
1206 SMF_GOTOS(EStRestart) |
1346 SMF_GOTOS(EStRestart) |
1298 }; |
1452 }; |
1299 |
1453 |
1300 __KTRACE_OPT(KPBUS1,Kern::Printf(">SD:SwitchToHighSpeedModeSM ")); |
1454 __KTRACE_OPT(KPBUS1,Kern::Printf(">SD:SwitchToHighSpeedModeSM ")); |
1301 |
1455 |
1302 DMMCSession& s = Session(); |
1456 DMMCSession& s = Session(); |
|
1457 OstTrace1( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM, "Current session = 0x%x", &s ); |
1303 |
1458 |
1304 SMF_BEGIN |
1459 SMF_BEGIN |
1305 |
1460 |
|
1461 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM1, "EStBegin"); |
|
1462 |
1306 SMF_STATE(EstCheckController) |
1463 SMF_STATE(EstCheckController) |
|
1464 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM2, "EstCheckController"); |
1307 // Get the clock speed supported by the controller |
1465 // Get the clock speed supported by the controller |
1308 TMMCMachineInfoV4 machineInfo; |
1466 TMMCMachineInfoV4 machineInfo; |
1309 TMMCMachineInfoV4Pckg machineInfoPckg(machineInfo); |
1467 TMMCMachineInfoV4Pckg machineInfoPckg(machineInfo); |
1310 MachineInfo(machineInfoPckg); |
1468 MachineInfo(machineInfoPckg); |
1311 |
1469 |
1312 if (machineInfo.iVersion >= TMMCMachineInfoV4::EVersion4) |
1470 if (machineInfo.iVersion >= TMMCMachineInfoV4::EVersion4) |
1313 { |
1471 { |
1314 if (machineInfo.iMaxClockSpeedInMhz < (KSDDTClk50MHz/1000) ) |
1472 if (machineInfo.iMaxClockSpeedInMhz < (KSDDTClk50MHz/1000) ) |
1315 { |
1473 { |
1316 __KTRACE_OPT(KPBUS1, Kern::Printf("High speed mode not supported by controller")); |
1474 __KTRACE_OPT(KPBUS1, Kern::Printf("High speed mode not supported by controller")); |
|
1475 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM3, "High speed mode not supported by controller"); |
1317 SMF_GOTOS(EStDone); |
1476 SMF_GOTOS(EStDone); |
1318 } |
1477 } |
1319 } |
1478 } |
1320 |
1479 |
1321 SMF_STATE(EStSendSCRCmd) |
1480 SMF_STATE(EStSendSCRCmd) |
|
1481 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM4, "EStSendSCRCmd"); |
1322 // |
1482 // |
1323 // ACMD51 Read the SD Configuration Register |
1483 // ACMD51 Read the SD Configuration Register |
1324 // |
1484 // |
1325 DSDSession::FillAppCommandDesc(Command(), ESDACmdSendSCR); |
1485 DSDSession::FillAppCommandDesc(Command(), ESDACmdSendSCR); |
1326 s.FillCommandArgs(0, KSDSCRLength, iPSLBuf, KSDSCRLength); |
1486 s.FillCommandArgs(0, KSDSCRLength, iPSLBuf, KSDSCRLength); |
1327 SMF_INVOKES(ExecCommandSMST, EStCheckSpecVer); |
1487 SMF_INVOKES(ExecCommandSMST, EStCheckSpecVer); |
1328 |
1488 |
1329 SMF_STATE(EStCheckSpecVer) |
1489 SMF_STATE(EStCheckSpecVer) |
|
1490 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM5, "EStCheckSpecVer"); |
1330 // |
1491 // |
1331 // Check the SD version |
1492 // Check the SD version |
1332 // |
1493 // |
1333 // 0 : version 1.0-1.01 : SDHS Is NOT Supported |
1494 // 0 : version 1.0-1.01 : SDHS Is NOT Supported |
1334 // 1 : version 1.10+ : SDHS Is Supported |
1495 // 1 : version 1.10+ : SDHS Is Supported |
1335 // |
1496 // |
1336 __KTRACE_OPT(KPBUS1,Kern::Printf(" SD Configuration Register received")); |
1497 __KTRACE_OPT(KPBUS1,Kern::Printf(" SD Configuration Register received")); |
1337 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...card_status=%x", TUint(s.iLastStatus))); |
1498 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...card_status=%x", TUint(s.iLastStatus))); |
|
1499 OstTrace1( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM6, "SD Configuration Register received: card_status=0x%x", (TUint) s.iLastStatus); |
1338 |
1500 |
1339 #ifdef _DEBUG |
1501 #ifdef _DEBUG |
1340 for (TUint32 i = 0; i < KSDSCRLength; ++i) |
1502 for (TUint32 i = 0; i < KSDSCRLength; ++i) |
1341 { |
1503 { |
1342 __KTRACE_OPT(KPBUS1, Kern::Printf(" ...SCR_STATUS[0x%x] = %x", i, iPSLBuf[i])); |
1504 __KTRACE_OPT(KPBUS1, Kern::Printf(" ...SCR_STATUS[0x%x] = %x", i, iPSLBuf[i])); |
1344 #endif |
1506 #endif |
1345 |
1507 |
1346 if(iPSLBuf[0]==2) |
1508 if(iPSLBuf[0]==2) |
1347 { |
1509 { |
1348 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version 2")); |
1510 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version 2")); |
|
1511 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM7, "SD Spec Version 2"); |
1349 SMF_GOTOS(EStCheckFunction); |
1512 SMF_GOTOS(EStCheckFunction); |
1350 } |
1513 } |
1351 |
1514 |
1352 if(iPSLBuf[0]==1) |
1515 if(iPSLBuf[0]==1) |
1353 { |
1516 { |
1354 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version 1.10")); |
1517 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version 1.10")); |
|
1518 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM8, "SD Spec Version 1.10"); |
1355 SMF_GOTOS(EStCheckFunction); |
1519 SMF_GOTOS(EStCheckFunction); |
1356 } |
1520 } |
1357 |
1521 |
1358 if(iPSLBuf[0]==0) |
1522 if(iPSLBuf[0]==0) |
1359 { |
1523 { |
1360 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version 1.01")); |
1524 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version 1.01")); |
|
1525 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM9, "SD Spec Version 1.01"); |
1361 SMF_GOTOS(EStDone); |
1526 SMF_GOTOS(EStDone); |
1362 } |
1527 } |
1363 |
1528 |
1364 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version > 2 !")); |
1529 __KTRACE_OPT(KPBUS1,Kern::Printf(" ...SD Spec Version > 2 !")); |
|
1530 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM10, "SD Spec Version > 2"); |
1365 |
1531 |
1366 SMF_STATE(EStCheckFunction) |
1532 SMF_STATE(EStCheckFunction) |
1367 |
1533 |
|
1534 OstTrace0( TRACE_INTERNALS, DSDSTACK_SWITCHTOHIGHSPEEDMODESM11, "EStCheckFunction"); |
1368 m.SetTraps(KMMCErrResponseTimeOut | KMMCErrNotSupported); |
1535 m.SetTraps(KMMCErrResponseTimeOut | KMMCErrNotSupported); |
1369 |
1536 |
1370 // |
1537 // |
1371 // SD1.1 uses CMD6 which is not defined by the MMCA |
1538 // SD1.1 uses CMD6 which is not defined by the MMCA |
1372 // - fill in command details using the SD Specific command description table |
1539 // - fill in command details using the SD Specific command description table |