|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // LDD for testing SDIO functions |
|
15 // |
|
16 // |
|
17 |
|
18 #include <kernel/kernel.h> |
|
19 #include "regifc.h" |
|
20 #include "cisreader.h" |
|
21 #include "d_sdioif.h" |
|
22 |
|
23 /** |
|
24 Define the name of the LDD. |
|
25 |
|
26 @internal |
|
27 @test |
|
28 */ |
|
29 _LIT(KLddName,"D_SDIOIF"); |
|
30 |
|
31 /** |
|
32 Define the version of the LDD. |
|
33 |
|
34 @internal |
|
35 @test |
|
36 */ |
|
37 const TInt KMajorVersionNumber=1; |
|
38 const TInt KMinorVersionNumber=0; |
|
39 const TInt KBuildVersionNumber=1; |
|
40 |
|
41 /** |
|
42 Define the default socket number. |
|
43 |
|
44 @internal |
|
45 @test |
|
46 */ |
|
47 #ifdef __WINS__ |
|
48 const TInt KSocketNumber = 0; |
|
49 #else |
|
50 const TInt KSocketNumber = 0; |
|
51 // const TInt KSocketNumber = 1; // 1 for Integrator!! |
|
52 #endif |
|
53 |
|
54 /** |
|
55 Define the default stack number. |
|
56 |
|
57 @internal |
|
58 @test |
|
59 */ |
|
60 const TInt KStackNumber = 0; |
|
61 |
|
62 /** |
|
63 Define the default card number. |
|
64 |
|
65 @internal |
|
66 @test |
|
67 */ |
|
68 const TInt KCardNumber = 0; |
|
69 |
|
70 /** |
|
71 Define an invalid function number outside the normal 0-7 range. |
|
72 |
|
73 @internal |
|
74 @test |
|
75 */ |
|
76 const TUint8 KInvalidFuncNum = 8; |
|
77 |
|
78 /** |
|
79 Define the global Dfc Que. |
|
80 |
|
81 @internal |
|
82 @test |
|
83 */ |
|
84 TDynamicDfcQue* gDfcQ; |
|
85 |
|
86 class DTestFactory : public DLogicalDevice |
|
87 /** |
|
88 Class to act as a factory for the test LDD |
|
89 |
|
90 @internal |
|
91 @test |
|
92 */ |
|
93 { |
|
94 public: |
|
95 DTestFactory(); |
|
96 ~DTestFactory(); |
|
97 virtual TInt Install(); //overriding pure virtual |
|
98 virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual |
|
99 virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual |
|
100 }; |
|
101 |
|
102 |
|
103 class DTest : public DLogicalChannel |
|
104 /** |
|
105 Class containing the logical device driver to drive the SDIO classes. |
|
106 |
|
107 @internal |
|
108 @test |
|
109 */ |
|
110 { |
|
111 public: |
|
112 DTest(); |
|
113 virtual ~DTest(); |
|
114 protected: |
|
115 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
116 virtual void HandleMsg(class TMessageBase *); |
|
117 virtual TInt SendMsg(TMessageBase* aMsg); |
|
118 private: |
|
119 TInt SendRequest(TMessageBase* aMsg); |
|
120 TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); |
|
121 TInt SendControl(TMessageBase* aMsg); |
|
122 TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); |
|
123 TInt CheckForChangeOfCis(TInt aFunc); |
|
124 TInt DoCancel(TUint aMask); |
|
125 static void EventCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2); |
|
126 |
|
127 private: |
|
128 // The SDIO objects |
|
129 DMMCSocket* iSocketP; |
|
130 DMMCStack* iStackP; |
|
131 TSDIOCard* iCardP; |
|
132 TInt iFunc; |
|
133 TCisReader iCisRd; |
|
134 |
|
135 DThread* iClient; |
|
136 TPBusCallBack iBusEventCallback; |
|
137 |
|
138 // Client requests used for creating local copies of user requests, WDP safe |
|
139 TClientRequest* iPowerUpRequest; |
|
140 TClientRequest* iResetCisRequest; |
|
141 TClientDataRequest<TSDIOCardConfig>* iCardCommonReadRequest; |
|
142 TClientDataRequest<TSDIOFunctionCaps>* iFunctionCapsRequest; |
|
143 TClientDataRequest<TUint>* iReadDirectRequest; // Use TUint rather than TUint8 for alignment purposes |
|
144 }; |
|
145 |
|
146 DECLARE_STANDARD_LDD() |
|
147 /** |
|
148 The standard entry point for logical device drivers. |
|
149 |
|
150 @internal |
|
151 @test |
|
152 */ |
|
153 { |
|
154 return new DTestFactory; |
|
155 } |
|
156 |
|
157 DTestFactory::DTestFactory() |
|
158 /** |
|
159 Constructor. |
|
160 |
|
161 @internal |
|
162 @test |
|
163 */ |
|
164 { |
|
165 iParseMask=KDeviceAllowUnit; |
|
166 iUnitsMask=0xffffffff; |
|
167 iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
168 } |
|
169 |
|
170 TInt DTestFactory::Create(DLogicalChannelBase*& aChannel) |
|
171 /** |
|
172 Create a new DTest on this logical device. |
|
173 |
|
174 @return One of the system wide error codes. |
|
175 |
|
176 @internal |
|
177 @test |
|
178 */ |
|
179 { |
|
180 aChannel=new DTest; |
|
181 return aChannel?KErrNone:KErrNoMemory; |
|
182 } |
|
183 |
|
184 const TInt KDSdioIfThreadPriority = 27; |
|
185 _LIT(KDSdioIfThread,"DSdioIfThread"); |
|
186 |
|
187 TInt DTestFactory::Install() |
|
188 /** |
|
189 Install the LDD - overriding pure virtual. |
|
190 |
|
191 @return One of the system wide error codes. |
|
192 |
|
193 @internal |
|
194 @test |
|
195 */ |
|
196 { |
|
197 // Allocate a kernel thread to run the DFC |
|
198 TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDSdioIfThreadPriority, KDSdioIfThread); |
|
199 |
|
200 if (r != KErrNone) |
|
201 return r; |
|
202 |
|
203 return SetName(&KLddName); |
|
204 } |
|
205 |
|
206 void DTestFactory::GetCaps(TDes8& aDes) const |
|
207 /** |
|
208 Return the capabilities of the LDD. |
|
209 |
|
210 @return A packaged TCapsTestV01. |
|
211 |
|
212 @internal |
|
213 @test |
|
214 */ |
|
215 { |
|
216 TCapsTestV01 b; |
|
217 b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
218 Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b)); |
|
219 } |
|
220 |
|
221 DTestFactory::~DTestFactory() |
|
222 /** |
|
223 Destructor |
|
224 |
|
225 @internal |
|
226 @test |
|
227 */ |
|
228 { |
|
229 if (gDfcQ) |
|
230 gDfcQ->Destroy(); |
|
231 } |
|
232 |
|
233 TInt DTest::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer) |
|
234 /** |
|
235 Create a logical channel. |
|
236 |
|
237 @param aUnit The socket number. |
|
238 @param aInfo Not used. |
|
239 @param aVer The version requested. |
|
240 |
|
241 @return KErrNone if the channel was created. KErrNotSupported if the version is not supported |
|
242 otherwise one of the system wide error codes. |
|
243 |
|
244 @internal |
|
245 @test |
|
246 */ |
|
247 { |
|
248 |
|
249 if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) |
|
250 return KErrNotSupported; |
|
251 |
|
252 // Create the asynchronous callback client request |
|
253 TInt ret = Kern::CreateClientRequest(iPowerUpRequest); |
|
254 if (ret != KErrNone) |
|
255 return ret; |
|
256 |
|
257 ret = Kern::CreateClientRequest(iResetCisRequest); |
|
258 if (ret != KErrNone) |
|
259 return ret; |
|
260 |
|
261 ret = Kern::CreateClientDataRequest(iReadDirectRequest); |
|
262 if (ret != KErrNone) |
|
263 return ret; |
|
264 |
|
265 ret = Kern::CreateClientDataRequest(iCardCommonReadRequest); |
|
266 if (ret != KErrNone) |
|
267 return ret; |
|
268 |
|
269 ret = Kern::CreateClientDataRequest(iFunctionCapsRequest); |
|
270 if (ret != KErrNone) |
|
271 return ret; |
|
272 |
|
273 // |
|
274 // Obtain the appropriate card from the socket/stack |
|
275 // |
|
276 iSocketP = static_cast<DMMCSocket*>(DPBusSocket::SocketFromId(KSocketNumber)); |
|
277 if(iSocketP == NULL) |
|
278 return KErrNoMemory; |
|
279 |
|
280 iStackP = static_cast<DSDIOStack*>(iSocketP->Stack(KStackNumber)); |
|
281 if(iStackP == NULL) |
|
282 return KErrNoMemory; |
|
283 |
|
284 iCardP = static_cast<TSDIOCard*>(iStackP->CardP(KCardNumber)); |
|
285 if(iCardP == NULL) |
|
286 return KErrNoMemory; |
|
287 |
|
288 iFunc=KInvalidFuncNum; // Indicates Cis reader isn't selected |
|
289 |
|
290 SetDfcQ(gDfcQ); |
|
291 iMsgQ.Receive(); |
|
292 |
|
293 iBusEventCallback.SetSocket(aUnit); |
|
294 iBusEventCallback.Add(); |
|
295 |
|
296 return KErrNone; |
|
297 } |
|
298 |
|
299 DTest::DTest() |
|
300 /** |
|
301 Constructor. |
|
302 |
|
303 @internal |
|
304 @test |
|
305 */ |
|
306 : iBusEventCallback(DTest::EventCallBack, this) |
|
307 { |
|
308 iClient=&Kern::CurrentThread(); |
|
309 ((DObject*)iClient)->Open(); // can't fail since thread is running |
|
310 } |
|
311 |
|
312 |
|
313 DTest::~DTest() |
|
314 /** |
|
315 Destructor. |
|
316 |
|
317 @internal |
|
318 @test |
|
319 */ |
|
320 { |
|
321 iBusEventCallback.Remove(); |
|
322 |
|
323 // Destroy the client requests |
|
324 Kern::DestroyClientRequest(iPowerUpRequest); |
|
325 Kern::DestroyClientRequest(iResetCisRequest); |
|
326 Kern::DestroyClientRequest(iReadDirectRequest); |
|
327 Kern::DestroyClientRequest(iCardCommonReadRequest); |
|
328 Kern::DestroyClientRequest(iFunctionCapsRequest); |
|
329 |
|
330 Kern::SafeClose((DObject*&)iClient,NULL); |
|
331 } |
|
332 |
|
333 /** |
|
334 Pre-process the received message to prepare the client's request. |
|
335 |
|
336 @param aMsg A pointer to a message (request) from the user side. |
|
337 @return One of the system wide error codes. |
|
338 |
|
339 @internal |
|
340 @test |
|
341 */ |
|
342 TInt DTest::SendMsg(TMessageBase* aMsg) |
|
343 { |
|
344 TThreadMessage& m = *(TThreadMessage*)aMsg; |
|
345 TInt id = m.iValue; |
|
346 |
|
347 // we only support one client |
|
348 if (id != (TInt)ECloseMsg && m.Client() != iClient) |
|
349 return KErrAccessDenied; |
|
350 |
|
351 TInt r = KErrNone; |
|
352 if (id != (TInt)ECloseMsg && id != KMaxTInt) |
|
353 { |
|
354 if (id<0) |
|
355 { |
|
356 // It's a request |
|
357 TRequestStatus* pS = (TRequestStatus*)m.Ptr0(); |
|
358 |
|
359 // Pre-process the request |
|
360 r = SendRequest(aMsg); |
|
361 if (r != KErrNone) |
|
362 Kern::RequestComplete(pS,r); |
|
363 } |
|
364 else |
|
365 { |
|
366 // Pre-process the control |
|
367 r = SendControl(aMsg); |
|
368 } |
|
369 } |
|
370 else |
|
371 r = DLogicalChannel::SendMsg(aMsg); |
|
372 |
|
373 return r; |
|
374 } |
|
375 |
|
376 /** |
|
377 Handle a request message from the user side RSdioCardCntrlIf. |
|
378 |
|
379 @param aMsg A pointer to a message (request) from the user side. |
|
380 |
|
381 @internal |
|
382 @test |
|
383 */ |
|
384 void DTest::HandleMsg(TMessageBase* aMsg) |
|
385 { |
|
386 TThreadMessage& m=*(TThreadMessage*)aMsg; |
|
387 TInt id=m.iValue; |
|
388 |
|
389 if (id==(TInt)ECloseMsg) |
|
390 { |
|
391 // Check for a close message |
|
392 m.Complete(KErrNone, EFalse); |
|
393 return; |
|
394 } |
|
395 else if (id==KMaxTInt) |
|
396 { |
|
397 // DoCancel |
|
398 DoCancel(m.Int0()); |
|
399 m.Complete(KErrNone, ETrue); |
|
400 return; |
|
401 } |
|
402 |
|
403 if (id<0) |
|
404 { |
|
405 // DoRequest |
|
406 TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); |
|
407 TInt r=DoRequest(~id, pS, m.Ptr1(), m.Ptr2()); |
|
408 if (r!=KErrNone) |
|
409 Kern::RequestComplete(iClient, pS, r); |
|
410 m.Complete(KErrNone,ETrue); |
|
411 } |
|
412 else |
|
413 { |
|
414 // DoControl |
|
415 TInt r=DoControl(id,m.Ptr0(),m.Ptr1()); |
|
416 m.Complete(r,ETrue); |
|
417 } |
|
418 } |
|
419 |
|
420 /** |
|
421 Handle a pre-process for a request message from the user side RSdioCardCntrlIf. |
|
422 This will set-up the client requests. |
|
423 |
|
424 @param aMsg A pointer to a message (request) from the user side. |
|
425 @return One of the system wide error codes. |
|
426 |
|
427 @internal |
|
428 @test |
|
429 */ |
|
430 TInt DTest::SendRequest(TMessageBase* aMsg) |
|
431 { |
|
432 TThreadMessage& m = *(TThreadMessage*)aMsg; |
|
433 TInt function = ~m.iValue; |
|
434 TRequestStatus* pS = (TRequestStatus*)m.Ptr0(); |
|
435 TAny* a2 = m.Ptr2(); |
|
436 |
|
437 TInt r = KErrNotSupported; |
|
438 switch (function) |
|
439 { |
|
440 // A request to power up the SDIO card & stack |
|
441 case RSdioCardCntrlIf::EReqPwrUp: |
|
442 r = iPowerUpRequest->SetStatus(pS); |
|
443 if (r != KErrNone) |
|
444 return r; |
|
445 break; |
|
446 // A request to read generic data from the SDIO card |
|
447 case RSdioCardCntrlIf::ERequestReadDirect: |
|
448 { |
|
449 r = iReadDirectRequest->SetStatus(pS); |
|
450 if (r != KErrNone) |
|
451 return r; |
|
452 iReadDirectRequest->SetDestPtr(a2); |
|
453 } |
|
454 break; |
|
455 // A request to reset the CIS pointer |
|
456 case RSdioCardCntrlIf::ERequestResetCis: |
|
457 r = iResetCisRequest->SetStatus(pS); |
|
458 if (r != KErrNone) |
|
459 return r; |
|
460 break; |
|
461 |
|
462 // A request to read the Card Common Config |
|
463 case RSdioCardCntrlIf::ERequestGetCommonConfig: |
|
464 { |
|
465 r = iCardCommonReadRequest->SetStatus(pS); |
|
466 if (r != KErrNone) |
|
467 return r; |
|
468 iCardCommonReadRequest->SetDestPtr(a2); |
|
469 } |
|
470 break; |
|
471 |
|
472 // A request to read the function data (FBR) |
|
473 case RSdioCardCntrlIf::ERequestGetFunctionConfig: |
|
474 { |
|
475 r = iFunctionCapsRequest->SetStatus(pS); |
|
476 if (r != KErrNone) |
|
477 return r; |
|
478 iFunctionCapsRequest->SetDestPtr(a2); |
|
479 } |
|
480 break; |
|
481 } |
|
482 |
|
483 if (r == KErrNone) |
|
484 r = DLogicalChannel::SendMsg(aMsg); |
|
485 return r; |
|
486 } |
|
487 |
|
488 /** |
|
489 Process any asynchronous requests from the user side. |
|
490 |
|
491 @param aFunction The asynchronous function to invoke. |
|
492 @param aStatus On completion, the success code for the function. |
|
493 @param a1 Context sensitive data. |
|
494 @param a2 Context sensitive data. |
|
495 |
|
496 @return One of the system wide error codes. |
|
497 |
|
498 @internal |
|
499 @test |
|
500 */ |
|
501 TInt DTest::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2) |
|
502 { |
|
503 TInt r=KErrNone; |
|
504 TInt func = (TInt)a1; |
|
505 switch (aFunction) |
|
506 { |
|
507 // A request to power up the SDIO card & stack |
|
508 case RSdioCardCntrlIf::EReqPwrUp: |
|
509 { |
|
510 if(!iSocketP->CardIsPresent()) |
|
511 { |
|
512 // An SDIO card is not present |
|
513 Kern::QueueRequestComplete(iClient, iPowerUpRequest, KErrNotReady); |
|
514 } |
|
515 else if(iSocketP->State() == EPBusOn) |
|
516 { |
|
517 // The card is already powered up |
|
518 Kern::QueueRequestComplete(iClient, iPowerUpRequest, KErrNone); |
|
519 } |
|
520 else |
|
521 { |
|
522 // Power up the card |
|
523 iSocketP->PowerUp(); |
|
524 } |
|
525 break; |
|
526 } |
|
527 |
|
528 // A request to read generic data from the SDIO card |
|
529 case RSdioCardCntrlIf::ERequestReadDirect: |
|
530 { |
|
531 TInt addr = (TInt)a1; |
|
532 |
|
533 TUint8 val = 0; |
|
534 r = iCardP->CommonRegisterInterface()->Read8(addr, &val); |
|
535 if(r == KErrNone) |
|
536 { |
|
537 iReadDirectRequest->Data() = (TUint)val; |
|
538 } |
|
539 |
|
540 Kern::QueueRequestComplete(iClient, iReadDirectRequest, r); |
|
541 break; |
|
542 } |
|
543 |
|
544 // A request to reset the CIS pointer |
|
545 case RSdioCardCntrlIf::ERequestResetCis: |
|
546 { |
|
547 if ((r=CheckForChangeOfCis(func))==KErrNone) |
|
548 { |
|
549 iCisRd.Restart(); |
|
550 } |
|
551 |
|
552 Kern::QueueRequestComplete(iClient, iResetCisRequest, r); |
|
553 break; |
|
554 } |
|
555 |
|
556 // A request to read the card common config |
|
557 case RSdioCardCntrlIf::ERequestGetCommonConfig: |
|
558 { |
|
559 if ((r=CheckForChangeOfCis(func))==KErrNone) |
|
560 { |
|
561 memset(&iCardCommonReadRequest->Data(), 0, sizeof(TSDIOCardConfig)); |
|
562 |
|
563 r = iCisRd.FindReadCommonConfig(iCardCommonReadRequest->Data()); |
|
564 Kern::QueueRequestComplete(iClient, iCardCommonReadRequest, r); |
|
565 } |
|
566 break; |
|
567 } |
|
568 |
|
569 // A request to read the function data (FBR) |
|
570 case RSdioCardCntrlIf::ERequestGetFunctionConfig: |
|
571 { |
|
572 if ((r=CheckForChangeOfCis(func))==KErrNone) |
|
573 { |
|
574 memset(&iFunctionCapsRequest->Data(), 0, sizeof(TSDIOFunctionCaps)); |
|
575 |
|
576 r=iCisRd.FindReadFunctionConfig(iFunctionCapsRequest->Data()); |
|
577 Kern::QueueRequestComplete(iClient, iFunctionCapsRequest, r); |
|
578 } |
|
579 break; |
|
580 } |
|
581 |
|
582 default: |
|
583 r=KErrNotSupported; |
|
584 break; |
|
585 } |
|
586 return r; |
|
587 } |
|
588 |
|
589 /** |
|
590 Surround the DoControl command, creating a kernel copy of the user side data, then copying back afterwards |
|
591 |
|
592 @param aMsg The message |
|
593 @return One of the system wide error codes. |
|
594 |
|
595 @internal |
|
596 @test |
|
597 */ |
|
598 TInt DTest::SendControl(TMessageBase* aMsg) |
|
599 { |
|
600 TThreadMessage& m = *(TThreadMessage*)aMsg; |
|
601 TInt id = m.iValue; |
|
602 |
|
603 TSdioCardInfo kernelCardInfo; |
|
604 TAny* userCardInfoPtr = m.Ptr0(); |
|
605 |
|
606 // thread-local copy of configuration data |
|
607 switch (id) |
|
608 { |
|
609 case RSdioCardCntrlIf::ESvCardInfo: |
|
610 // copy config from client to local buffer in context of client thread |
|
611 umemget32(&kernelCardInfo, userCardInfoPtr, sizeof(TSdioCardInfo)); |
|
612 // update message to point to kernel-side buffer |
|
613 m.iArg[0] = &kernelCardInfo; |
|
614 break; |
|
615 } |
|
616 |
|
617 TInt r = DLogicalChannel::SendMsg(aMsg); |
|
618 if (r != KErrNone) |
|
619 return r; |
|
620 |
|
621 switch (id) |
|
622 { |
|
623 case RSdioCardCntrlIf::ESvCardInfo: |
|
624 // copy config from local bufferto client in context of client thread |
|
625 umemput32(userCardInfoPtr, &kernelCardInfo, sizeof(TSdioCardInfo)); |
|
626 break; |
|
627 } |
|
628 |
|
629 return r; |
|
630 } |
|
631 |
|
632 /** |
|
633 Process any synchronous requests from the user side. |
|
634 |
|
635 @param aFunction The synchronous function to invoke. |
|
636 @param a1 Context sensitive data. |
|
637 @param a2 Context sensitive data. |
|
638 |
|
639 @return One of the system wide error codes. |
|
640 |
|
641 @internal |
|
642 @test |
|
643 */ |
|
644 TInt DTest::DoControl(TInt aFunction, TAny* a1, TAny* /*a2*/) |
|
645 { |
|
646 TInt r=KErrNone; |
|
647 switch (aFunction) |
|
648 { |
|
649 // Read the card information data |
|
650 case RSdioCardCntrlIf::ESvCardInfo: |
|
651 { |
|
652 if(iCardP) |
|
653 { |
|
654 iCardP->CheckCIS(); |
|
655 TSdioCardInfo* cardInfoPtr = (TSdioCardInfo*)a1; |
|
656 TSdioCardInfo& info = *cardInfoPtr; |
|
657 |
|
658 // |
|
659 // Extract the card information |
|
660 // |
|
661 info.isComboCard=iCardP->IsComboCard(); |
|
662 info.iIsReady=iCardP->IsPresent(); |
|
663 info.iIsLocked=iCardP->IsLocked(); |
|
664 info.iCardSpeed=iCardP->MaxTranSpeedInKilohertz(); |
|
665 TCID* cid=(TCID*)&(iCardP->CID()); |
|
666 TInt i; |
|
667 for (i=0;i<16;i++) |
|
668 info.iCID[i]=cid->At(i); |
|
669 const TCSD& csd = iCardP->CSD(); |
|
670 for (i=0;i<16;i++) |
|
671 info.iCSD[i]=csd.At(i); |
|
672 info.iRCA=TUint16(iCardP->RCA()); |
|
673 info.iMediaType=TMmcMediaType(iCardP->MediaType()); |
|
674 |
|
675 // |
|
676 // Extract the function information |
|
677 // |
|
678 info.iFuncCount = iCardP->FunctionCount(); |
|
679 |
|
680 TSDIOFunctionCaps functionCaps; |
|
681 TSDIOFunction* functionP = NULL; |
|
682 |
|
683 for(TUint8 func=0; func<=info.iFuncCount; func++) |
|
684 { |
|
685 functionP = iCardP->IoFunction((TUint8) (func)); |
|
686 if(functionP) |
|
687 { |
|
688 functionCaps = functionP->Capabilities(); |
|
689 info.iFunction[func].iType = (TSdioFunctionType)(functionCaps.iType); |
|
690 } |
|
691 } |
|
692 } |
|
693 else |
|
694 { |
|
695 r = KErrGeneral; |
|
696 } |
|
697 |
|
698 break; |
|
699 } |
|
700 default: |
|
701 r=KErrNotSupported; |
|
702 break; |
|
703 } |
|
704 return r; |
|
705 } |
|
706 |
|
707 |
|
708 /** |
|
709 Check if diferent function selected, select new CIS if necessary. |
|
710 |
|
711 @param aFunc The SDIO function. |
|
712 |
|
713 @return One of the system wide error codes. |
|
714 |
|
715 @internal |
|
716 @test |
|
717 */ |
|
718 TInt DTest::CheckForChangeOfCis(TInt aFunc) |
|
719 { |
|
720 |
|
721 if (iFunc!=aFunc||iFunc==KInvalidFuncNum) |
|
722 { |
|
723 TInt err; |
|
724 if ((err=iCisRd.SelectCis(KSocketNumber,0,0,(TUint8) aFunc))==KErrNone) |
|
725 iFunc=aFunc; |
|
726 return(err); |
|
727 } |
|
728 return(KErrNone); |
|
729 } |
|
730 |
|
731 /** |
|
732 Cancel an asynchronous request |
|
733 |
|
734 @param aMask Mask of requests to cancel |
|
735 @return One of the system wide error codes. |
|
736 |
|
737 @internal |
|
738 @test |
|
739 */ |
|
740 TInt DTest::DoCancel(TUint /*aMask*/) |
|
741 { |
|
742 if (iPowerUpRequest->IsReady()) |
|
743 { |
|
744 Kern::QueueRequestComplete(iClient, iPowerUpRequest, KErrCancel); |
|
745 } |
|
746 |
|
747 if (iResetCisRequest->IsReady()) |
|
748 { |
|
749 Kern::QueueRequestComplete(iClient, iPowerUpRequest, KErrCancel); |
|
750 } |
|
751 |
|
752 if (iCardCommonReadRequest->IsReady()) |
|
753 { |
|
754 Kern::QueueRequestComplete(iClient, iPowerUpRequest, KErrCancel); |
|
755 } |
|
756 |
|
757 if (iFunctionCapsRequest->IsReady()) |
|
758 { |
|
759 Kern::QueueRequestComplete(iClient, iPowerUpRequest, KErrCancel); |
|
760 } |
|
761 |
|
762 if (iReadDirectRequest->IsReady()) |
|
763 { |
|
764 Kern::QueueRequestComplete(iClient, iPowerUpRequest, KErrCancel); |
|
765 } |
|
766 |
|
767 return KErrNone; |
|
768 } |
|
769 |
|
770 /** |
|
771 Asynchronous call backs from the SDIO stack |
|
772 |
|
773 @param aPtr Data passed in when the callback was registered. |
|
774 @param aReason The reason for the callback, one of TPBusCallBack::EPBusStateChange |
|
775 or TPBusCallBack::EPBusCustomNotification. |
|
776 @param a1 Context sensitive data. |
|
777 @param a2 Context sensitive data. |
|
778 |
|
779 @return One of the system wide error codes. |
|
780 |
|
781 @internal |
|
782 @test |
|
783 */ |
|
784 void DTest::EventCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2) |
|
785 { |
|
786 DTest &mci = *(DTest*)aPtr; |
|
787 |
|
788 if (mci.iPowerUpRequest->IsReady()) |
|
789 { |
|
790 // There is an TRequestStatus pending |
|
791 TInt retCode = KErrCompletion; |
|
792 |
|
793 switch(aReason) |
|
794 { |
|
795 // There has been a state change |
|
796 case TPBusCallBack::EPBusStateChange: |
|
797 { |
|
798 TPBusState newState = (TPBusState)(TInt)a1; |
|
799 TInt errorCode = (TInt)a2; |
|
800 |
|
801 switch(newState) |
|
802 { |
|
803 case EPBusCardAbsent: retCode = KErrNotFound; break; |
|
804 case EPBusOff: retCode = errorCode; break; |
|
805 case EPBusPsuFault: retCode = KErrBadPower; break; |
|
806 case EPBusOn: retCode = KErrNone; break; |
|
807 case EPBusPowerUpPending: |
|
808 case EPBusPoweringUp: |
|
809 default: |
|
810 break; |
|
811 } |
|
812 |
|
813 break; |
|
814 } |
|
815 } |
|
816 |
|
817 if(retCode != KErrCompletion) |
|
818 { |
|
819 Kern::QueueRequestComplete(mci.iClient, mci.iPowerUpRequest, retCode); |
|
820 } |
|
821 } |
|
822 } |
|
823 |
|
824 |
|
825 |