31 #include "cbulkonlytransport.h" |
31 #include "cbulkonlytransport.h" |
32 #include "cusbhostmslogicalunit.h" |
32 #include "cusbhostmslogicalunit.h" |
33 #include "cusbhostmsdevice.h" |
33 #include "cusbhostmsdevice.h" |
34 #include "cusbmssuspendresume.h" |
34 #include "cusbmssuspendresume.h" |
35 |
35 |
36 #include "msdebug.h" |
36 #include "OstTraceDefinitions.h" |
37 #include "debug.h" |
37 #ifdef OST_TRACE_COMPILER_IN_USE |
|
38 #include "cusbhostmsdeviceTraces.h" |
|
39 #endif |
38 |
40 |
39 |
41 |
40 CUsbHostMsDevice* CUsbHostMsDevice::NewL(THostMassStorageConfig& aConfig) |
42 CUsbHostMsDevice* CUsbHostMsDevice::NewL(THostMassStorageConfig& aConfig) |
41 { |
43 { |
42 __MSFNSLOG |
44 CUsbHostMsDevice* r = new (ELeave) CUsbHostMsDevice(aConfig); |
43 CUsbHostMsDevice* r = new (ELeave) CUsbHostMsDevice(aConfig); |
45 CleanupStack::PushL(r); |
44 CleanupStack::PushL(r); |
46 r->ConstructL(); |
45 r->ConstructL(); |
47 CleanupStack::Pop(); |
46 CleanupStack::Pop(); |
48 return r; |
47 return r; |
49 } |
48 } |
|
49 |
50 |
50 void CUsbHostMsDevice::ConstructL() |
51 void CUsbHostMsDevice::ConstructL() |
51 { |
52 { |
52 __MSFNLOG |
53 iTimer = CPeriodic::NewL(CActive::EPriorityStandard); |
53 iTimer = CPeriodic::NewL(CActive::EPriorityStandard); |
54 iTimerRunning = EFalse; |
54 iTimerRunning = EFalse; |
|
55 } |
55 } |
56 |
56 |
57 |
57 |
58 CUsbHostMsDevice::CUsbHostMsDevice(THostMassStorageConfig& aConfig) |
58 CUsbHostMsDevice::CUsbHostMsDevice(THostMassStorageConfig& aConfig) |
59 : iConfig(aConfig), |
59 : iConfig(aConfig), |
60 iState(EReady) |
60 iState(EReady) |
61 { |
61 { |
62 __MSFNLOG |
62 } |
63 } |
|
64 |
63 |
65 |
64 |
66 CUsbHostMsDevice::~CUsbHostMsDevice() |
65 CUsbHostMsDevice::~CUsbHostMsDevice() |
67 { |
66 { |
68 __MSFNLOG |
67 delete iTransport; |
69 delete iTransport; |
68 delete iDeviceSuspendResume; |
70 delete iDeviceSuspendResume; |
69 if (iTimer && iTimerRunning) |
71 if (iTimer && iTimerRunning) |
70 { |
72 { |
71 iTimer->Cancel(); |
73 iTimer->Cancel(); |
72 } |
74 } |
73 delete iTimer; |
75 delete iTimer; |
74 } |
76 } |
|
77 |
75 |
78 |
76 |
79 MTransport* CUsbHostMsDevice::InitialiseTransportL(TTransportType aTransportId) |
77 MTransport* CUsbHostMsDevice::InitialiseTransportL(TTransportType aTransportId) |
80 { |
78 { |
81 __MSFNLOG |
79 switch(aTransportId) |
82 switch(aTransportId) |
80 { |
83 { |
81 case BulkOnlyTransport: |
84 case BulkOnlyTransport: |
82 return CBulkOnlyTransport::NewL(iConfig.iInterfaceToken); |
85 return CBulkOnlyTransport::NewL(iConfig.iInterfaceToken); |
83 default: |
86 default: |
84 // Panic; |
87 // Panic; |
85 OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, CUSBHOSTMSDEVICE_10, |
88 __HOSTPRINT(_L("Unsupported Transport class requested")); |
86 "Unsupported Transport class requested"); |
89 User::Leave(KErrNotSupported); |
87 User::Leave(KErrNotSupported); |
90 return NULL; |
88 return NULL; |
91 } |
89 } |
92 } |
90 } |
93 |
91 |
94 void CUsbHostMsDevice::InitialiseL(const RMessage2& aMessage) |
92 void CUsbHostMsDevice::InitialiseL(const RMessage2& aMessage) |
95 { |
93 { |
96 __MSFNLOG |
94 iTransport = InitialiseTransportL((TTransportType) iConfig.iTransportId); |
97 iTransport = InitialiseTransportL((TTransportType) iConfig.iTransportId); |
95 TRAPD(r, iDeviceSuspendResume = CUsbMsIfaceSuspendResume::NewL(iTransport, this)); |
98 TRAPD(r, iDeviceSuspendResume = CUsbMsIfaceSuspendResume::NewL(iTransport, this)); |
96 if(r != KErrNone) |
99 if(r != KErrNone) |
97 { |
100 { |
98 delete iTransport; |
101 delete iTransport; |
99 User::Leave(r); |
102 User::Leave(r); |
100 } |
103 } |
101 iTransport->GetMaxLun(&iMaxLun, aMessage); |
104 iTransport->GetMaxLun(&iMaxLun, aMessage); |
102 } |
105 } |
|
106 |
103 |
107 |
104 |
108 void CUsbHostMsDevice::UnInitialiseL() |
105 void CUsbHostMsDevice::UnInitialiseL() |
109 { |
106 { |
110 __MSFNLOG |
107 StopTimer(); |
111 StopTimer(); |
|
112 iLuList.RemoveAllLuL(); |
108 iLuList.RemoveAllLuL(); |
113 } |
109 } |
114 |
110 |
115 |
111 |
116 TInt CUsbHostMsDevice::AddLunL(TLun aLun) |
112 TInt CUsbHostMsDevice::AddLunL(TLun aLun) |
117 { |
113 { |
118 __MSFNLOG |
|
119 TInt r = KErrNone; |
114 TInt r = KErrNone; |
120 StartTimer(); |
115 StartTimer(); |
121 CUsbHostMsLogicalUnit* lu = CUsbHostMsLogicalUnit::NewL(aLun); |
116 CUsbHostMsLogicalUnit* lu = CUsbHostMsLogicalUnit::NewL(aLun); |
122 CleanupStack::PushL(lu); |
117 CleanupStack::PushL(lu); |
123 |
118 |
124 TRAP(r, lu->InitialiseProtocolL(aLun, iConfig, *iTransport)); |
119 TRAP(r, lu->InitialiseProtocolL(aLun, iConfig, *iTransport)); |
125 |
120 |
126 if (r == KErrNone) |
121 if (r == KErrNone) |
127 { |
122 { |
128 TRAP(r, iLuList.AddLuL(lu)); |
123 TRAP(r, iLuList.AddLuL(lu)); |
129 } |
124 } |
130 |
125 |
131 if (r != KErrNone) |
126 if (r != KErrNone) |
132 { |
127 { |
133 CleanupStack::PopAndDestroy(lu); |
128 CleanupStack::PopAndDestroy(lu); |
134 } |
129 } |
140 } |
135 } |
141 |
136 |
142 |
137 |
143 void CUsbHostMsDevice::RemoveLunL(TLun aLun) |
138 void CUsbHostMsDevice::RemoveLunL(TLun aLun) |
144 { |
139 { |
145 __MSFNLOG |
140 if(iLuList.Count() <= 1) |
146 if(iLuList.Count() <= 1) |
141 StopTimer(); |
147 StopTimer(); |
142 iLuList.RemoveLuL(aLun); |
148 iLuList.RemoveLuL(aLun); |
|
149 } |
143 } |
150 |
144 |
151 |
145 |
152 void CUsbHostMsDevice::InitLunL(TLun aLun) |
146 void CUsbHostMsDevice::InitLunL(TLun aLun) |
153 { |
147 { |
154 __MSFNLOG |
148 CUsbHostMsLogicalUnit& lu = SetLunL(aLun); |
155 CUsbHostMsLogicalUnit& lu = SetLunL(aLun); |
|
156 lu.InitL(); |
149 lu.InitL(); |
157 } |
150 } |
158 |
151 |
159 |
152 |
160 void CUsbHostMsDevice::SuspendLunL(TLun aLun) |
153 void CUsbHostMsDevice::SuspendLunL(TLun aLun) |
161 { |
154 { |
162 __MSFNLOG |
|
163 if (IsSuspended()) |
155 if (IsSuspended()) |
164 { |
156 { |
165 return; |
157 return; |
166 } |
158 } |
167 |
159 |
168 iLuList.GetLuL(aLun).ReadyToSuspend(); |
160 iLuList.GetLuL(aLun).ReadyToSuspend(); |
169 |
161 |
170 // check whether all the luns are suspended, if so then request usb |
162 // check whether all the luns are suspended, if so then request usb |
171 // interface suspension to the transport layer |
163 // interface suspension to the transport layer |
172 for (TInt i = 0; i < iLuList.Count(); i++) |
164 for (TInt i = 0; i < iLuList.Count(); i++) |
173 { |
165 { |
174 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
166 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
175 if (!lu.IsReadyToSuspend() && lu.IsConnected()) |
167 if (!lu.IsReadyToSuspend() && lu.IsConnected()) |
176 return; |
168 return; |
177 } |
169 } |
178 |
170 |
179 for (TInt i = 0; i < iLuList.Count(); i++) |
171 for (TInt i = 0; i < iLuList.Count(); i++) |
180 { |
172 { |
181 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
173 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
182 SetLunL(lu); |
174 SetLunL(lu); |
183 lu.SuspendL(); |
175 lu.SuspendL(); |
184 } |
176 } |
185 |
177 |
186 StopTimer(); |
178 StopTimer(); |
187 iDeviceSuspendResume->Suspend(); |
179 iDeviceSuspendResume->Suspend(); |
188 iState = ESuspended; |
180 iState = ESuspended; |
189 } |
181 } |
190 |
182 |
191 |
183 |
192 void CUsbHostMsDevice::Resume(TRequestStatus& aStatus) |
184 void CUsbHostMsDevice::Resume(TRequestStatus& aStatus) |
193 { |
185 { |
194 __MSFNLOG |
186 if (iState == ESuspended) |
195 if (iState == ESuspended) |
187 { |
196 { |
188 StartTimer(); |
197 StartTimer(); |
189 iDeviceSuspendResume->Resume(aStatus); |
198 iDeviceSuspendResume->Resume(aStatus); |
190 } |
199 } |
191 } |
200 } |
|
201 |
192 |
202 |
193 |
203 TLun CUsbHostMsDevice::GetAndSetLunL(const RMessage2& aMessage) |
194 TLun CUsbHostMsDevice::GetAndSetLunL(const RMessage2& aMessage) |
204 { |
195 { |
205 __MSFNLOG |
196 // Subssessions need a positive value to store in the handles. We represent Luns as LunId+1 |
206 // Subssessions need a positive value to store in the handles. We represent Luns as LunId+1 |
197 // We represent LunId in MSC from 0 to MaxLun-1 as represented in BOT so subtract 1 from the Id |
207 // We represent LunId in MSC from 0 to MaxLun-1 as represented in BOT so subtract 1 from the Id |
|
208 // received from RMessage |
198 // received from RMessage |
209 |
199 |
210 TInt lun = aMessage.Int3() - 1; |
200 TInt lun = aMessage.Int3() - 1; |
211 if (lun < 0) |
201 if (lun < 0) |
212 { |
202 { |
213 User::Leave(KErrArgument); |
203 User::Leave(KErrArgument); |
214 } |
204 } |
215 SetLunL(static_cast<TLun>(lun)); |
205 SetLunL(static_cast<TLun>(lun)); |
216 return static_cast<TLun>(lun); |
206 return static_cast<TLun>(lun); |
217 } |
207 } |
218 |
208 |
219 |
209 |
220 CUsbHostMsLogicalUnit& CUsbHostMsDevice::GetLuL(TInt aLunNum) const |
210 CUsbHostMsLogicalUnit& CUsbHostMsDevice::GetLuL(TInt aLunNum) const |
221 { |
211 { |
222 return iLuList.GetLuL(aLunNum); |
212 return iLuList.GetLuL(aLunNum); |
223 } |
213 } |
224 |
214 |
225 |
215 |
226 void CUsbHostMsDevice::SetLunL(CUsbHostMsLogicalUnit& aLu) |
216 void CUsbHostMsDevice::SetLunL(CUsbHostMsLogicalUnit& aLu) |
227 { |
217 { |
228 __MSFNLOG |
|
229 TLun lun = aLu.Lun(); |
218 TLun lun = aLu.Lun(); |
230 if (lun <= iMaxLun) |
219 if (lun <= iMaxLun) |
231 { |
220 { |
232 __HOSTPRINT1(_L("SetLun %d"), lun); |
221 OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, CUSBHOSTMSDEVICE_20, |
|
222 "SetLun %d", lun); |
233 iTransport->SetLun(lun); |
223 iTransport->SetLun(lun); |
234 if (aLu.IsReadyToSuspend()) |
224 if (aLu.IsReadyToSuspend()) |
235 { |
225 { |
236 aLu.CancelReadyToSuspend(); |
226 aLu.CancelReadyToSuspend(); |
237 } |
227 } |
238 } |
228 } |
239 } |
229 } |
240 |
230 |
241 |
231 |
242 CUsbHostMsLogicalUnit& CUsbHostMsDevice::SetLunL(TLun aLun) |
232 CUsbHostMsLogicalUnit& CUsbHostMsDevice::SetLunL(TLun aLun) |
243 { |
233 { |
244 __MSFNLOG |
|
245 CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(aLun); |
234 CUsbHostMsLogicalUnit& lu = iLuList.GetLuL(aLun); |
246 SetLunL(lu); |
235 SetLunL(lu); |
247 return lu; |
236 return lu; |
248 } |
237 } |
249 |
238 |
250 /** |
239 /** |
251 Starts timer to periodically check LUN. If the timer is not yet running then |
240 Starts timer to periodically check LUN. If the timer is not yet running then |
252 start it. |
241 start it. |
253 */ |
242 */ |
254 void CUsbHostMsDevice::StartTimer() |
243 void CUsbHostMsDevice::StartTimer() |
255 { |
244 { |
256 __MSFNLOG |
245 if (!iTimerRunning) |
257 if (!iTimerRunning) |
246 { |
258 { |
247 // Period of the LUN Ready check |
259 // Period of the LUN Ready check |
248 const TTimeIntervalMicroSeconds32 KInterval = iConfig.iStatusPollingInterval * 1000 * 1000; |
260 const TTimeIntervalMicroSeconds32 KInterval = iConfig.iStatusPollingInterval * 1000 * 1000; |
249 TCallBack callback(TimerCallback, this); |
261 TCallBack callback(TimerCallback, this); |
250 OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, CUSBHOSTMSDEVICE_21, |
262 __HOSTPRINT(_L("Starting timer")); |
251 "Starting timer"); |
263 iTimer->Start(KInterval, KInterval, callback); |
252 iTimer->Start(KInterval, KInterval, callback); |
264 iTimerRunning = ETrue; |
253 iTimerRunning = ETrue; |
265 } |
254 } |
266 } |
255 } |
267 |
256 |
268 |
257 |
269 /** |
258 /** |
270 Ensure that the Timer is stopped |
259 Ensure that the Timer is stopped |
271 */ |
260 */ |
272 void CUsbHostMsDevice::StopTimer() |
261 void CUsbHostMsDevice::StopTimer() |
273 { |
262 { |
274 __MSFNLOG |
263 if (iTimer && iTimerRunning) |
275 if (iTimer && iTimerRunning) |
264 { |
276 { |
265 OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, CUSBHOSTMSDEVICE_30, |
277 __HOSTPRINT(_L("Stopping timer")); |
266 "Stopping timer"); |
278 if (iTimer->IsActive()) |
267 if (iTimer->IsActive()) |
279 { |
268 { |
280 iTimer->Cancel(); |
269 iTimer->Cancel(); |
281 } |
270 } |
282 iTimerRunning = EFalse; |
271 iTimerRunning = EFalse; |
283 } |
272 } |
284 } |
273 } |
285 |
274 |
286 /** |
275 /** |
287 A static wrapper for the DoLunReadyCheckEvent member function for use as a timer |
276 A static wrapper for the DoLunReadyCheckEvent member function for use as a timer |
288 callback function. |
277 callback function. |
289 |
278 |
290 @param obj 'this' pointer |
279 @param obj 'this' pointer |
291 @return not used in CPeriodic callback (see TCallback) |
280 @return not used in CPeriodic callback (see TCallback) |
292 */ |
281 */ |
293 TInt CUsbHostMsDevice::TimerCallback(TAny* obj) |
282 TInt CUsbHostMsDevice::TimerCallback(TAny* obj) |
294 { |
283 { |
295 __MSFNSLOG |
|
296 CUsbHostMsDevice* device = static_cast<CUsbHostMsDevice*>(obj); |
284 CUsbHostMsDevice* device = static_cast<CUsbHostMsDevice*>(obj); |
297 TRAPD(err, device->DoLunReadyCheckEventL()); |
285 TRAPD(err, device->DoLunReadyCheckEventL()); |
298 return err; |
286 return err; |
299 } |
287 } |
300 |
288 |
301 void CUsbHostMsDevice::DoLunReadyCheckEventL() |
289 void CUsbHostMsDevice::DoLunReadyCheckEventL() |
302 { |
290 { |
303 __MSFNLOG |
291 TInt err; |
304 TInt err; |
292 for (TInt i = 0; i < iLuList.Count(); i++) |
305 for (TInt i = 0; i < iLuList.Count(); i++) |
293 { |
306 { |
294 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
307 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
295 SetLunL(lu); |
308 SetLunL(lu); |
296 TRAP(err, lu.DoLunReadyCheckL()); |
309 TRAP(err, lu.DoLunReadyCheckL()); |
297 } |
310 } |
298 } |
311 } |
|
312 |
299 |
313 void CUsbHostMsDevice::DoHandleRemoteWakeupL() |
300 void CUsbHostMsDevice::DoHandleRemoteWakeupL() |
314 { |
301 { |
315 __MSFNLOG |
302 DoResumeLogicalUnitsL(); |
316 DoResumeLogicalUnitsL(); |
303 DoLunReadyCheckEventL(); // For remote wakeup we do not wait for timer to expire |
317 DoLunReadyCheckEventL(); // For remote wakeup we do not wait for timer to expire |
|
318 |
304 |
319 // check whether all the luns are suspended, if so then request usb |
305 // check whether all the luns are suspended, if so then request usb |
320 // interface suspension to the transport layer |
306 // interface suspension to the transport layer |
321 for (TInt i = 0; i < iLuList.Count(); i++) |
307 for (TInt i = 0; i < iLuList.Count(); i++) |
322 { |
308 { |
323 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
309 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
324 // Has any of the logical units have got its state changed? |
310 // Has any of the logical units have got its state changed? |
325 if ( (lu.IsReadyToSuspend() && !lu.IsConnected()) || |
311 if ( (lu.IsReadyToSuspend() && !lu.IsConnected()) || |
326 (!lu.IsReadyToSuspend() && lu.IsConnected()) ) |
312 (!lu.IsReadyToSuspend() && lu.IsConnected()) ) |
327 { |
313 { |
328 StartTimer(); // Now start the timer |
314 StartTimer(); // Now start the timer |
329 return; |
315 return; |
330 } |
316 } |
331 } |
317 } |
332 |
318 |
333 for (TInt i = 0; i < iLuList.Count(); i++) |
319 for (TInt i = 0; i < iLuList.Count(); i++) |
334 { |
320 { |
335 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
321 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
336 SetLunL(lu); |
322 SetLunL(lu); |
337 lu.SuspendL(); |
323 lu.SuspendL(); |
338 } |
324 } |
339 |
325 |
340 iDeviceSuspendResume->Suspend(); |
326 iDeviceSuspendResume->Suspend(); |
341 iState = ESuspended; |
327 iState = ESuspended; |
342 } |
328 } |
343 |
329 |
344 void CUsbHostMsDevice::DoResumeLogicalUnitsL() |
330 void CUsbHostMsDevice::DoResumeLogicalUnitsL() |
345 { |
331 { |
346 __MSFNLOG |
332 for (TInt i = 0; i < iLuList.Count(); i++) |
347 for (TInt i = 0; i < iLuList.Count(); i++) |
333 { |
348 { |
334 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
349 CUsbHostMsLogicalUnit& lu = iLuList.GetLu(i); |
335 SetLunL(lu); |
350 SetLunL(lu); |
336 lu.ResumeL(); |
351 lu.ResumeL(); |
337 } |
352 } |
338 } |
353 } |
|
354 |
339 |
355 void CUsbHostMsDevice::ResumeCompletedL() |
340 void CUsbHostMsDevice::ResumeCompletedL() |
356 { |
341 { |
357 __MSFNLOG |
342 iState = EReady; |
358 iState = EReady; |
343 DoResumeLogicalUnitsL(); |
359 DoResumeLogicalUnitsL(); |
344 } |
360 } |
|