author | hgs |
Tue, 02 Nov 2010 15:42:21 +0000 | |
changeset 301 | 172f33f13d7d |
parent 300 | 1d28c8722707 |
permissions | -rw-r--r-- |
119 | 1 |
// Copyright (c) 2008-2010 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". |
|
0 | 7 |
// |
119 | 8 |
// Initial Contributors: |
9 |
// Nokia Corporation - initial contribution. |
|
0 | 10 |
// |
119 | 11 |
// Contributors: |
12 |
// |
|
13 |
// Description: |
|
14 |
// This file system extension provides a way to access a drive on the MS system |
|
15 |
// in "raw format". It can be used to test large files / drives |
|
0 | 16 |
// |
17 |
||
18 |
/** @file |
|
19 |
@internalTechnology |
|
20 |
*/ |
|
21 |
||
22 |
#include <f32fsys.h> |
|
23 |
||
24 |
#include "hostusbmsproxy.h" |
|
300 | 25 |
#include "tmbr.h" |
26 |
||
27 |
#include "OstTraceDefinitions.h" |
|
28 |
#ifdef OST_TRACE_COMPILER_IN_USE |
|
29 |
static const TUint KBlockSize = 0x200; |
|
30 |
#include "hostusbmsproxyTraces.h" |
|
31 |
#endif |
|
0 | 32 |
|
33 |
||
34 |
CUsbHostMsProxyDrive::CUsbHostMsProxyDrive(CMountCB* aMount, CExtProxyDriveFactory* aDevice) |
|
35 |
: CExtProxyDrive(aMount,aDevice) |
|
300 | 36 |
{ |
37 |
} |
|
0 | 38 |
|
39 |
CUsbHostMsProxyDrive::~CUsbHostMsProxyDrive() |
|
300 | 40 |
{ |
41 |
iUsbHostMsLun.UnInitialise(); |
|
42 |
} |
|
0 | 43 |
|
44 |
TInt CUsbHostMsProxyDrive::InitialiseOffset(TCapsInfo& aCapsInfo) |
|
300 | 45 |
{ |
119 | 46 |
RBuf8 partitionInfo; |
47 |
TInt r; |
|
48 |
TRAP(r, partitionInfo.CreateL(aCapsInfo.iBlockLength)); |
|
49 |
if (r != KErrNone) |
|
50 |
{ |
|
51 |
return r; |
|
52 |
} |
|
0 | 53 |
|
300 | 54 |
r = iUsbHostMsLun.Read(0, aCapsInfo.iBlockLength, partitionInfo); |
55 |
if (r != KErrNone) |
|
0 | 56 |
{ |
300 | 57 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_10, |
58 |
"!! Reading medium failed with %d !!", r); |
|
0 | 59 |
} |
300 | 60 |
else |
61 |
{ |
|
62 |
TMBRPartitionEntry partitionEntry; |
|
63 |
TInt partitionCount = TMbr::GetPartition(partitionInfo, partitionEntry); |
|
0 | 64 |
|
300 | 65 |
if (partitionCount == 0) |
66 |
{ |
|
67 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_11, |
|
68 |
"No partition found"); |
|
69 |
iMsDataMemMap.InitDataArea(0, aCapsInfo.iNumberOfBlocks, aCapsInfo.iBlockLength); |
|
70 |
OstTraceExt3(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_12, |
|
71 |
"iFirstSector = x%x iNumSectors = x%x iSectorSize = x%x", |
|
72 |
0, |
|
73 |
aCapsInfo.iNumberOfBlocks, |
|
74 |
aCapsInfo.iBlockLength); |
|
0 | 75 |
|
300 | 76 |
} |
77 |
else if (partitionCount > 0) |
|
78 |
{ |
|
79 |
iMsDataMemMap.InitDataArea(partitionEntry.iFirstSector, |
|
119 | 80 |
partitionEntry.iNumSectors, |
81 |
aCapsInfo.iBlockLength); |
|
300 | 82 |
OstTraceExt3(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_13, |
83 |
"iFirstSector = x%x iNumSectors = x%x iSectorSize = x%x", |
|
84 |
partitionEntry.iFirstSector, |
|
85 |
partitionEntry.iNumSectors, |
|
86 |
aCapsInfo.iBlockLength); |
|
87 |
} |
|
88 |
else // MBR is not valid |
|
89 |
{ |
|
90 |
iMsDataMemMap.Reset(); |
|
91 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_14, |
|
92 |
"MBR not present"); |
|
93 |
} |
|
94 |
} |
|
95 |
partitionInfo.Close(); |
|
96 |
return r; |
|
97 |
} |
|
119 | 98 |
|
0 | 99 |
|
100 |
/** |
|
101 |
Initialise the proxy drive. |
|
102 |
@return system wide error code. |
|
103 |
*/ |
|
104 |
TInt CUsbHostMsProxyDrive::Initialise() |
|
300 | 105 |
{ |
106 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_20, |
|
107 |
">>> CUsbHostMsProxyDrive::Initialise()"); |
|
0 | 108 |
|
300 | 109 |
if(Mount()) |
110 |
{ |
|
111 |
// as we can't currently handle remounting devices that have |
|
112 |
// been removed by unplugging the USB cable, disable critical notifiers |
|
113 |
// as there's no point in asking the user to re-insert the disk. |
|
114 |
Mount()->SetNotifyOff(); |
|
115 |
} |
|
0 | 116 |
|
117 |
// Check for media presence |
|
300 | 118 |
TCapsInfo capsInfo; |
119 |
TInt err = iUsbHostMsLun.Caps(capsInfo); |
|
0 | 120 |
|
124 | 121 |
if (err == KErrNone && capsInfo.iMediaType == EMediaHardDisk) |
0 | 122 |
{ |
123 |
err = InitialiseOffset(capsInfo); |
|
124 |
} |
|
125 |
||
300 | 126 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_21, |
127 |
"<<< CUsbHostMsProxyDrive::Initialise() err = %d", err); |
|
0 | 128 |
return err; |
300 | 129 |
} |
0 | 130 |
|
131 |
TInt CUsbHostMsProxyDrive::SetInfo(const RMessage2 &msg, TAny* aMessageParam2, TAny* aMessageParam3) |
|
132 |
{ |
|
300 | 133 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_22, |
134 |
">>> CUsbHostMsProxyDrive::SetInfo()"); |
|
135 |
TMassStorageUnitInfo iUnitInfo; |
|
0 | 136 |
TPckg<TMassStorageUnitInfo> infoPckg(iUnitInfo); |
300 | 137 |
TRAPD(err, msg.ReadL(2, infoPckg)); |
0 | 138 |
|
300 | 139 |
if(err != KErrNone) |
140 |
{ |
|
141 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_23, |
|
142 |
"Cant read from the RMessage %d", err); |
|
143 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_24, |
|
144 |
"<<< CUsbHostMsProxyDrive::SetInfo() err = %d", err); |
|
145 |
return err; |
|
146 |
} |
|
0 | 147 |
|
300 | 148 |
err = iUsbHostMsLun.Initialise(msg, 3, iUnitInfo.iLunID); |
149 |
if(err != KErrNone) |
|
150 |
{ |
|
151 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_25, |
|
152 |
"Initialising logical unit failed %d", err); |
|
153 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_26, |
|
154 |
"<<< CUsbHostMsProxyDrive::SetInfo() err = %d", err); |
|
155 |
return err; |
|
156 |
} |
|
0 | 157 |
|
300 | 158 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_27, |
159 |
"<<< CUsbHostMsProxyDrive::SetInfo() err = %d", err); |
|
160 |
return err; |
|
0 | 161 |
} |
162 |
||
163 |
TInt CUsbHostMsProxyDrive::Dismounted() |
|
300 | 164 |
{ |
165 |
return KErrNone; |
|
166 |
} |
|
0 | 167 |
|
168 |
TInt CUsbHostMsProxyDrive::Enlarge(TInt /*aLength*/) |
|
300 | 169 |
{ |
170 |
return KErrNotSupported; |
|
171 |
} |
|
0 | 172 |
|
173 |
||
174 |
TInt CUsbHostMsProxyDrive::ReduceSize(TInt /*aPos*/, TInt /*aLength*/) |
|
300 | 175 |
{ |
176 |
return KErrNotSupported; |
|
177 |
} |
|
0 | 178 |
|
300 | 179 |
#define GetIndex(msg, aAddress, aIndex) \ |
180 |
aIndex = msg.Ptr0() == aAddress ? 0 : \ |
|
181 |
msg.Ptr1() == aAddress ? 1 : \ |
|
182 |
msg.Ptr1() == aAddress ? 2 : \ |
|
183 |
msg.Ptr1() == aAddress ? 3 : -1; |
|
0 | 184 |
|
185 |
/** |
|
186 |
Read from the proxy drive. |
|
187 |
||
188 |
@param aPos The address from where the read begins. |
|
189 |
@param aLength The length of the read. |
|
190 |
@param aTrg A descriptor of the memory buffer from which to read. |
|
191 |
@param aThreadHandle The handle-number representing the drive thread. |
|
192 |
@param aOffset Offset into aTrg to read the data from. |
|
193 |
||
194 |
@return system wide error code. |
|
195 |
*/ |
|
196 |
TInt CUsbHostMsProxyDrive::Read(TInt64 aPos, TInt aLength, |
|
197 |
const TAny* aTrg, TInt aThreadHandle, TInt aOffset) |
|
300 | 198 |
{ |
199 |
OstTraceExt4(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_300, |
|
200 |
">>> HOST Read Pos=0x%x %x LBA=0x%x %x", |
|
201 |
I64HIGH(aPos), I64LOW(aPos), I64HIGH(aPos/KBlockSize), I64LOW(aPos/KBlockSize)); |
|
202 |
OstTraceExt2(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_301, |
|
203 |
">>> Len 0x%x Offset 0x%x", |
|
204 |
(TUint)aLength, (TUint)aOffset); |
|
0 | 205 |
|
300 | 206 |
TBool localMessage = (aThreadHandle == KLocalMessageHandle); |
0 | 207 |
|
300 | 208 |
// |
209 |
// Set file position to where we want to read... |
|
210 |
// |
|
211 |
if(!localMessage) |
|
212 |
{ |
|
213 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
214 |
localMessage = (msg.Handle() == KLocalMessageHandle); |
|
215 |
} |
|
0 | 216 |
|
300 | 217 |
TInt index = 0; |
218 |
if (!localMessage) |
|
219 |
{ |
|
220 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
221 |
GetIndex(msg, aTrg, index); |
|
0 | 222 |
|
300 | 223 |
if (index < 0) |
0 | 224 |
{ |
300 | 225 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_302, |
226 |
"<<< HOST Read ret=%d", KErrArgument); |
|
0 | 227 |
return KErrArgument; |
228 |
} |
|
300 | 229 |
} |
0 | 230 |
|
300 | 231 |
/* Calculate the end position */ |
232 |
TInt64 end = aPos + static_cast<TInt64>(aLength); |
|
0 | 233 |
|
300 | 234 |
/* check whether there is enough source data to write to the destination descriptor */ |
235 |
TInt64 truncate; |
|
236 |
if(localMessage) |
|
237 |
{ |
|
238 |
truncate = aLength - (((TPtr8* )aTrg)->MaxLength() - aOffset); |
|
239 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_303, |
|
240 |
"Descriptor length: %08x", ((TPtr8* )aTrg)->MaxLength()); |
|
241 |
} |
|
242 |
else |
|
243 |
{ |
|
244 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
245 |
truncate = aLength - (msg.GetDesMaxLength(index) - aOffset); |
|
246 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_304, |
|
247 |
"Descriptor length: %08x", msg.GetDesMaxLength(index)); |
|
248 |
} |
|
0 | 249 |
|
300 | 250 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_305, |
251 |
"Offset: %08x", aOffset); |
|
252 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_306, |
|
253 |
"Truncate: 0x%lx", truncate); |
|
0 | 254 |
|
300 | 255 |
if (truncate > 0) |
256 |
{ |
|
257 |
end -= truncate; |
|
258 |
} |
|
0 | 259 |
|
300 | 260 |
iBuf.SetMax(); |
0 | 261 |
TInt r; |
262 |
TInt64 mediaPos; |
|
300 | 263 |
while (aPos < end) |
0 | 264 |
{ |
300 | 265 |
TInt len = end - aPos; |
0 | 266 |
mediaPos = aPos; |
267 |
r = iMsDataMemMap.CheckBlockInRange(mediaPos, len); |
|
268 |
if (r != KErrNone) |
|
269 |
{ |
|
300 | 270 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_307, |
271 |
"<<< HOST Read ret=%d", r); |
|
0 | 272 |
return r; |
273 |
} |
|
274 |
||
300 | 275 |
if (localMessage) |
276 |
{ |
|
277 |
TPtr8* pTrgPtr = (TPtr8*)aTrg; |
|
278 |
TPtr8 trgDes((TUint8*)(pTrgPtr->MidTPtr(aOffset).Ptr()), pTrgPtr->MaxLength() - aOffset); |
|
279 |
r = iUsbHostMsLun.Read(mediaPos, len, trgDes); |
|
280 |
if (r != KErrNone) |
|
281 |
return r; |
|
282 |
pTrgPtr->SetLength(aOffset + trgDes.Length()); |
|
283 |
} |
|
284 |
else |
|
285 |
{ |
|
286 |
if (len > iBuf.MaxLength()) |
|
287 |
len = iBuf.MaxLength(); |
|
0 | 288 |
|
289 |
r = iUsbHostMsLun.Read(mediaPos, len, iBuf); |
|
300 | 290 |
if (r != KErrNone) |
0 | 291 |
{ |
300 | 292 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_308, |
293 |
"<<< HOST Read ret=%d", r); |
|
0 | 294 |
return r; |
295 |
} |
|
296 |
||
300 | 297 |
iBuf.SetLength(len); |
0 | 298 |
|
300 | 299 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
300 |
r = msg.Write(index, iBuf, aOffset); |
|
301 |
if (r != KErrNone) |
|
0 | 302 |
{ |
300 | 303 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_309, |
304 |
"<<< HOST Read ret=%d", r); |
|
0 | 305 |
return r; |
306 |
} |
|
300 | 307 |
} |
0 | 308 |
|
309 |
aPos += len; |
|
310 |
aOffset += len; |
|
311 |
} |
|
312 |
||
300 | 313 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_310, |
314 |
"<<< HOST Read ret=%d", KErrNone); |
|
315 |
return KErrNone; |
|
316 |
} |
|
0 | 317 |
|
318 |
||
319 |
/** |
|
320 |
Read from the proxy drive, and pass flags to driver. |
|
321 |
||
322 |
@param aPos The address from where the read begins. |
|
323 |
@param aLength The length of the read. |
|
324 |
@param aTrg A descriptor of the memory buffer from which to read. |
|
325 |
@param aThreadHandle The handle-number representing the drive thread. |
|
326 |
@param aOffset Offset into aTrg to read the data from. |
|
327 |
@param aFlags Flags to be passed into the driver. |
|
328 |
||
329 |
@return system wide error code. |
|
330 |
*/ |
|
331 |
TInt CUsbHostMsProxyDrive::Read(TInt64 aPos, TInt aLength, |
|
332 |
const TAny* aTrg, TInt aThreadHandle, TInt aOffset, TInt /* aFlags */) |
|
300 | 333 |
{ |
334 |
return Read(aPos, aLength, aTrg, aThreadHandle, aOffset); |
|
335 |
} |
|
0 | 336 |
|
337 |
/** |
|
338 |
Read from the proxy drive. |
|
339 |
||
340 |
@param aPos The address from where the read begins. |
|
341 |
@param aLength The length of the read. |
|
342 |
@param aTrg A descriptor of the memory buffer from which to read. |
|
343 |
||
344 |
@return system wide error code. |
|
345 |
*/ |
|
346 |
TInt CUsbHostMsProxyDrive::Read(TInt64 aPos, TInt aLength, TDes8& aTrg) |
|
300 | 347 |
{ |
348 |
OstTraceExt5(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_40, |
|
349 |
">>> HOST Read Pos=0x%x %x LBA=0x%x %x 0x%x", |
|
350 |
I64HIGH(aPos), I64LOW(aPos), I64HIGH(aPos/KBlockSize), I64LOW(aPos/KBlockSize), aLength); |
|
351 |
return iUsbHostMsLun.Read(iMsDataMemMap.GetDataPos(aPos), aLength, aTrg); |
|
352 |
} |
|
0 | 353 |
|
354 |
/** |
|
355 |
Write to the proxy drive. |
|
356 |
||
357 |
@param aPos The address from where the write begins. |
|
358 |
@param aLength The length of the write. |
|
359 |
@param aSrc A descriptor of the memory buffer from which to write. |
|
360 |
@param aThreadHandle The handle-number representing the drive thread. |
|
361 |
@param aOffset Offset into aSrc to write the data to. |
|
362 |
||
363 |
@return system wide error code. |
|
364 |
*/ |
|
365 |
TInt CUsbHostMsProxyDrive::Write(TInt64 aPos, TInt aLength, |
|
366 |
const TAny* aSrc, TInt aThreadHandle, TInt aOffset) |
|
300 | 367 |
{ |
368 |
// |
|
369 |
// Set file position to where we want to write... |
|
370 |
// |
|
371 |
OstTraceExt4(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_50, |
|
372 |
">>> HOST Write Pos=0x%x %x LBA=0%x %x", |
|
373 |
I64HIGH(aPos), I64LOW(aPos), I64HIGH(aPos/KBlockSize), I64LOW(aPos/KBlockSize)); |
|
374 |
OstTraceExt2(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_501, |
|
375 |
"Len=0x%x Offset=0x%x", |
|
376 |
(TUint)aLength, (TUint)aOffset); |
|
0 | 377 |
|
300 | 378 |
TBool localMessage = (aThreadHandle == KLocalMessageHandle); |
0 | 379 |
|
300 | 380 |
if(!localMessage) |
381 |
{ |
|
382 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
383 |
localMessage = (msg.Handle() == KLocalMessageHandle); |
|
384 |
} |
|
0 | 385 |
|
300 | 386 |
TInt index = 0; |
387 |
if(!localMessage) |
|
388 |
{ |
|
389 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
390 |
GetIndex(msg, aSrc, index); |
|
0 | 391 |
|
300 | 392 |
if (index < 0) |
393 |
return KErrArgument; |
|
394 |
} |
|
0 | 395 |
|
300 | 396 |
/* Calculate the end position */ |
397 |
TInt64 end = aPos + static_cast<TInt64>(aLength); |
|
398 |
/* check whether there is enough source data to read */ |
|
399 |
TInt64 truncate; |
|
400 |
if (localMessage) |
|
401 |
{ |
|
402 |
truncate = aLength - (((TPtr8* )aSrc)->Length() - aOffset); |
|
403 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_51, |
|
404 |
"Descriptor length: %08x", ((TPtr8* )aSrc)->Length()); |
|
405 |
} |
|
406 |
else |
|
407 |
{ |
|
408 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
409 |
truncate = aLength - (msg.GetDesLength(index) - aOffset); |
|
410 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_52, |
|
411 |
"Descriptor length: %08x", msg.GetDesLength(index)); |
|
412 |
} |
|
0 | 413 |
|
300 | 414 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_53, |
415 |
"Offset: %08x", aOffset); |
|
416 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_PROXY, HOSTUSBMSPROXY_54, |
|
417 |
"Truncate: 0x%lx", truncate); |
|
0 | 418 |
|
300 | 419 |
/* if truncate is > 0 we are short of source data as claimed by the aLength. Hence adjust the 'end' */ |
420 |
if (truncate > 0) |
|
421 |
{ |
|
422 |
end -= truncate; |
|
423 |
} |
|
0 | 424 |
|
300 | 425 |
iBuf.SetMax(); |
0 | 426 |
|
427 |
TInt r; |
|
428 |
TInt64 mediaPos; |
|
300 | 429 |
while (aPos < end) |
0 | 430 |
{ |
300 | 431 |
TInt len = end - aPos; |
0 | 432 |
mediaPos = aPos; |
433 |
r = iMsDataMemMap.CheckBlockInRange(mediaPos, len); |
|
434 |
if (r != KErrNone) |
|
435 |
{ |
|
300 | 436 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_55, |
437 |
"<<< HOST Write ret=%d", r); |
|
0 | 438 |
return r; |
439 |
} |
|
440 |
||
300 | 441 |
if (localMessage) |
442 |
{ |
|
443 |
r = iUsbHostMsLun.Write(mediaPos, len, ((TPtr8*)aSrc)->MidTPtr(aOffset)); |
|
0 | 444 |
|
300 | 445 |
if (r != KErrNone) |
0 | 446 |
{ |
300 | 447 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_56, |
448 |
"<<< HOST Write ret=%d", r); |
|
0 | 449 |
return r; |
450 |
} |
|
300 | 451 |
} |
452 |
else |
|
453 |
{ |
|
454 |
if (len > iBuf.Length()) |
|
455 |
len = iBuf.Length(); |
|
0 | 456 |
|
300 | 457 |
RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
458 |
r = msg.Read(index, iBuf, aOffset); |
|
459 |
if (r != KErrNone) |
|
0 | 460 |
{ |
300 | 461 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_57, |
462 |
"<<< HOST Write ret=%d", r); |
|
0 | 463 |
return r; |
464 |
} |
|
465 |
||
300 | 466 |
r = iUsbHostMsLun.Write(mediaPos, len, iBuf); |
467 |
if (r != KErrNone) |
|
0 | 468 |
{ |
300 | 469 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_58, |
470 |
"<<< HOST Write ret=%d", r); |
|
0 | 471 |
return r; |
472 |
} |
|
300 | 473 |
} |
0 | 474 |
|
475 |
aPos += len; |
|
476 |
aOffset += len; |
|
477 |
} |
|
478 |
||
300 | 479 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_59, |
480 |
"<<< HOST Write ret=%d", KErrNone); |
|
481 |
return KErrNone; |
|
482 |
} |
|
0 | 483 |
|
119 | 484 |
|
0 | 485 |
/** |
486 |
Write to the proxy drive and pass flags to driver |
|
487 |
||
488 |
@param aPos The address from where the write begins. |
|
489 |
@param aLength The length of the write. |
|
490 |
@param aSrc A descriptor of the memory buffer from which to write. |
|
491 |
@param aThreadHandle The handle-number representing the drive thread. |
|
492 |
@param aOffset Offset into aSrc to write the data to. |
|
493 |
@param aFlags Flags to be passed into the driver. |
|
494 |
||
495 |
@return system wide error code. |
|
496 |
*/ |
|
497 |
TInt CUsbHostMsProxyDrive::Write(TInt64 aPos, TInt aLength, |
|
498 |
const TAny* aSrc, TInt aThreadHandle, TInt aOffset, TInt /* aFlags */) |
|
300 | 499 |
{ |
500 |
return Write(aPos, aLength, aSrc, aThreadHandle, aOffset); |
|
501 |
} |
|
0 | 502 |
|
503 |
/** |
|
504 |
Write to the proxy drive. |
|
505 |
||
506 |
@param aPos The address from where the write begins. |
|
507 |
@param aSrc A descriptor of the memory buffer from which to write. |
|
508 |
||
509 |
@return system wide error code. |
|
510 |
*/ |
|
511 |
TInt CUsbHostMsProxyDrive::Write(TInt64 aPos,const TDesC8& aSrc) |
|
300 | 512 |
{ |
513 |
OstTraceExt5(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_60, |
|
514 |
">>> HOST Write Pos=0x%x %x LBA=0x%x %x Len=0x%x", |
|
515 |
I64HIGH(aPos), I64LOW(aPos), I64HIGH(aPos/KBlockSize), I64LOW(aPos/KBlockSize), aSrc.Length()); |
|
516 |
return iUsbHostMsLun.Write(iMsDataMemMap.GetDataPos(aPos), aSrc.Length(), aSrc); |
|
517 |
} |
|
0 | 518 |
|
119 | 519 |
|
0 | 520 |
/** |
521 |
Get the proxy drive's capabilities information. |
|
522 |
||
523 |
@param anInfo A descriptor of the connected drives capabilities. |
|
524 |
||
525 |
@return system wide error code |
|
526 |
*/ |
|
527 |
TInt CUsbHostMsProxyDrive::Caps(TDes8& anInfo) |
|
300 | 528 |
{ |
529 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_70, |
|
530 |
">>> HOST Caps"); |
|
531 |
TLocalDriveCapsV6Buf caps; |
|
0 | 532 |
caps.FillZ(); |
533 |
||
33
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
534 |
TLocalDriveCapsV6& c = caps(); |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
535 |
|
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
536 |
c.iConnectionBusType = EConnectionBusUsb; |
300 | 537 |
c.iDriveAtt = KDriveAttLocal | KDriveAttRemovable | KDriveAttExternal; |
538 |
c.iMediaAtt = KMediaAttFormattable; |
|
539 |
c.iFileSystemId = KDriveFileSysFAT; |
|
0 | 540 |
|
300 | 541 |
TCapsInfo capsInfo; |
542 |
TInt r = iUsbHostMsLun.Caps(capsInfo); |
|
124 | 543 |
|
300 | 544 |
if (KErrNone == r) |
545 |
{ |
|
124 | 546 |
c.iType = capsInfo.iMediaType; |
0 | 547 |
|
124 | 548 |
if (capsInfo.iMediaType == EMediaHardDisk) |
0 | 549 |
{ |
124 | 550 |
c.iBlockSize = capsInfo.iBlockLength; |
551 |
TUint64 size = iMsDataMemMap.DataSize(); |
|
300 | 552 |
|
124 | 553 |
if (size == 0) |
554 |
{ |
|
555 |
// No valid partitions so specify the size of the disk |
|
556 |
size = static_cast<TUint64>(capsInfo.iNumberOfBlocks) * capsInfo.iBlockLength; |
|
557 |
} |
|
558 |
c.iSize = size; |
|
300 | 559 |
|
124 | 560 |
c.iEraseBlockSize = 0; |
300 | 561 |
|
124 | 562 |
if (capsInfo.iWriteProtect) |
563 |
{ |
|
564 |
c.iMediaAtt |= KMediaAttWriteProtected; |
|
565 |
} |
|
300 | 566 |
|
124 | 567 |
static const TInt K512ByteSectorSize = 0x200; // 512 |
568 |
if(K512ByteSectorSize != capsInfo.iBlockLength) |
|
569 |
{ |
|
570 |
// not formattable if sector size is not 512 |
|
571 |
c.iMediaAtt &= ~KMediaAttFormattable; |
|
572 |
} |
|
300 | 573 |
OstTraceExt2(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_710, |
574 |
"<<< HOST Caps Block[num=0x%x size=0x%x]", |
|
575 |
capsInfo.iNumberOfBlocks, capsInfo.iBlockLength); |
|
576 |
OstTraceExt2(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_711, |
|
577 |
"Media size=0x%x %x", I64HIGH(caps().iSize), I64LOW(caps().iSize)); |
|
578 |
OstTrace1(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_712, |
|
579 |
"WP=0x%x", caps().iMediaAtt); |
|
0 | 580 |
} |
124 | 581 |
else if (capsInfo.iMediaType == EMediaCdRom) |
582 |
{ |
|
583 |
// not formattable |
|
584 |
c.iMediaAtt &= ~KMediaAttFormattable; |
|
300 | 585 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_72, |
586 |
">>> HOST Caps MediaType = EMediaCdRom"); |
|
124 | 587 |
} |
588 |
else |
|
589 |
{ |
|
590 |
// do nothing |
|
591 |
} |
|
300 | 592 |
} |
593 |
else if (KErrNotReady == r) |
|
0 | 594 |
{ |
300 | 595 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_73, |
596 |
"<<< HOST Caps Media Not Present"); |
|
597 |
c.iType = EMediaNotPresent; |
|
598 |
r = KErrNone; |
|
119 | 599 |
} |
300 | 600 |
else if (KErrGeneral == r) |
127 | 601 |
{ |
300 | 602 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_74, |
603 |
"<<< HOST Caps Unable to communicate with media"); |
|
604 |
c.iType = EMediaUnknown; |
|
127 | 605 |
} |
606 |
||
119 | 607 |
else |
608 |
{ |
|
300 | 609 |
OstTrace0(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_75, |
610 |
"<<< HOST Caps Unknown Error"); |
|
119 | 611 |
c.iType = EMediaUnknown; |
300 | 612 |
r = KErrUnknown; |
0 | 613 |
} |
300 | 614 |
anInfo = caps.Left(Min(caps.Length(),anInfo.MaxLength())); |
615 |
return r; |
|
616 |
} |
|
0 | 617 |
|
618 |
||
619 |
/** |
|
620 |
Format the proxy drive. The drive is assumed to be a single partition. The |
|
621 |
partition size is equivalent to the size of the media. |
|
622 |
||
623 |
@param aPos The position of the data which is being formatted. |
|
624 |
@param aLength [IN] The length of the data which is being formatted. [OUT] The |
|
625 |
length of data formatted, truncated when end of drive is reached. |
|
626 |
||
627 |
@return system wide error code. |
|
628 |
*/ |
|
629 |
TInt CUsbHostMsProxyDrive::Erase(TInt64 aPos, TInt& aLength) |
|
300 | 630 |
{ |
631 |
OstTraceExt5(TRACE_SHOSTMASSSTORAGE_HOST, HOSTUSBMSPROXY_80, |
|
632 |
"HOST Erase Pos=0x%x %x LBA=0x%x %x 0x%x", |
|
633 |
I64HIGH(aPos), I64LOW(aPos), I64HIGH(aPos/KBlockSize), I64LOW(aPos/KBlockSize), aLength); |
|
0 | 634 |
TInt err = iMsDataMemMap.TranslateDataPos(aPos, aLength); |
635 |
||
636 |
if (err) |
|
637 |
return err; |
|
638 |
||
639 |
err = iUsbHostMsLun.Erase(aPos, aLength); |
|
640 |
return err; |
|
300 | 641 |
} |
0 | 642 |
|
643 |
||
644 |
/** |
|
645 |
Format the proxy drive. |
|
646 |
||
647 |
@param aPos The position of the data which is being formatted. |
|
648 |
@param aLength The length of the data which is being formatted. |
|
649 |
||
650 |
@return system wide error code. |
|
651 |
*/ |
|
652 |
TInt CUsbHostMsProxyDrive::Format(TInt64 aPos, TInt aLength) |
|
300 | 653 |
{ |
0 | 654 |
return Erase(aPos, aLength); |
300 | 655 |
} |
0 | 656 |
|
657 |
||
658 |
/** |
|
659 |
Format the connected drive. |
|
660 |
||
661 |
@param anInfo Device specific format information. |
|
662 |
||
663 |
@return system wide error code. |
|
664 |
*/ |
|
665 |
TInt CUsbHostMsProxyDrive::Format(TFormatInfo& aInfo) |
|
300 | 666 |
{ |
119 | 667 |
const TInt KDefaultMaxBytesPerFormat = 0x100 * iMsDataMemMap.BlockLength(); // 128K |
0 | 668 |
|
669 |
if (aInfo.i512ByteSectorsFormatted < 0) |
|
670 |
return KErrArgument; |
|
671 |
||
672 |
if (!aInfo.iFormatIsCurrent) |
|
673 |
{ |
|
674 |
aInfo.iFormatIsCurrent = ETrue; |
|
675 |
aInfo.i512ByteSectorsFormatted = 0; |
|
676 |
aInfo.iMaxBytesPerFormat = KDefaultMaxBytesPerFormat; |
|
677 |
||
300 | 678 |
TLocalDriveCapsV6Buf caps; |
679 |
TInt r = Caps(caps); |
|
680 |
if (r != KErrNone) |
|
681 |
return r; |
|
0 | 682 |
|
683 |
iMsDataMemMap.InitDataArea(caps().iSize); |
|
684 |
} |
|
685 |
||
119 | 686 |
TInt64 pos = static_cast<TInt64>(aInfo.i512ByteSectorsFormatted) << iMsDataMemMap.FormatSectorShift(); |
0 | 687 |
TInt length = aInfo.iMaxBytesPerFormat; |
688 |
TInt r = Erase(pos, length); |
|
689 |
||
690 |
if (r == KErrNone) |
|
691 |
{ |
|
119 | 692 |
length += iMsDataMemMap.BlockLength() - 1; |
693 |
length >>= iMsDataMemMap.FormatSectorShift(); |
|
0 | 694 |
aInfo.i512ByteSectorsFormatted += length; |
695 |
} |
|
696 |
||
697 |
return r; |
|
698 |
} |
|
699 |
||
700 |
||
701 |
TInt CUsbHostMsProxyDrive::NotifyChange(TDes8 &aChanged,TRequestStatus* aStatus) |
|
300 | 702 |
{ |
703 |
iUsbHostMsLun.NotifyChange(aChanged, *aStatus); |
|
0 | 704 |
|
300 | 705 |
if(*aStatus != KRequestPending) |
706 |
return KErrUnknown; |
|
0 | 707 |
|
300 | 708 |
return KErrNone; |
709 |
} |
|
0 | 710 |
|
711 |
void CUsbHostMsProxyDrive::NotifyChangeCancel() |
|
300 | 712 |
{ |
713 |
iUsbHostMsLun.NotifyChangeCancel(); |
|
714 |
} |
|
0 | 715 |
|
716 |
TInt CUsbHostMsProxyDrive::SetMountInfo(const TDesC8* /*aMountInfo*/,TInt /*aMountInfoThreadHandle=KCurrentThreadHandle*/) |
|
717 |
{ |
|
718 |
return KErrNone; |
|
719 |
} |
|
720 |
||
721 |
TInt CUsbHostMsProxyDrive::ForceRemount(TUint aFlags) |
|
722 |
{ |
|
723 |
iUsbHostMsLun.ForceRemount(aFlags); |
|
724 |
return KErrNone; |
|
725 |
} |
|
726 |
||
727 |
TInt CUsbHostMsProxyDrive::Unlock(TMediaPassword& /*aPassword*/, TBool /*aStorePassword*/) |
|
728 |
{ |
|
729 |
return KErrNotSupported; |
|
730 |
} |
|
731 |
||
732 |
TInt CUsbHostMsProxyDrive::Lock(TMediaPassword& /*aOldPassword*/, TMediaPassword& /*aNewPassword*/, TBool /*aStorePassword*/) |
|
733 |
{ |
|
734 |
return KErrNotSupported; |
|
735 |
} |
|
736 |
||
737 |
TInt CUsbHostMsProxyDrive::Clear(TMediaPassword& /*aPassword*/) |
|
738 |
{ |
|
739 |
return KErrNotSupported; |
|
740 |
} |
|
741 |
||
742 |
TInt CUsbHostMsProxyDrive::ErasePassword() |
|
743 |
{ |
|
744 |
return KErrNotSupported; |
|
745 |
} |
|
746 |
||
747 |
TInt CUsbHostMsProxyDrive::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
|
300 | 748 |
{ |
749 |
switch(aInterfaceId) |
|
750 |
{ |
|
751 |
case ELocalBufferSupport: |
|
752 |
return KErrNone; |
|
753 |
case EFinalised: |
|
754 |
{ |
|
755 |
TBool isFinalised = (TBool)aInput; |
|
756 |
if(isFinalised) |
|
757 |
{ |
|
758 |
iUsbHostMsLun.SuspendLun(); |
|
759 |
} |
|
760 |
} |
|
761 |
return KErrNone; |
|
762 |
default: |
|
763 |
return KErrNotSupported; |
|
764 |
} |
|
765 |
} |