|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Device driver for SVP Host file system access |
|
15 * |
|
16 */ |
|
17 |
|
18 #ifdef __WINS__ |
|
19 #error - this driver cannot be built for emulation |
|
20 #endif |
|
21 |
|
22 #include <e32def.h> |
|
23 #include <e32cmn.h> |
|
24 #include <u32std.h> |
|
25 #include <kernel.h> |
|
26 #include <kern_priv.h> |
|
27 #include <arm.h> |
|
28 #include <cache.h> |
|
29 #include <nkern.h> |
|
30 #include <u32hal.h> |
|
31 |
|
32 #include <system.h> |
|
33 |
|
34 #include "rsvphostfsdriver.h" |
|
35 |
|
36 #include "libfdt.h" |
|
37 |
|
38 // Debug messages - uncomment define below |
|
39 //#define SVPDBG |
|
40 #ifdef SVPDBG |
|
41 #define DP(format...) Kern::Printf(format) |
|
42 #else |
|
43 #define DP(format...) |
|
44 #endif |
|
45 |
|
46 #define SVP_HOST_FS_DEVICE_ID 0xc51d0008 |
|
47 #define SVP_PLATFORM_DEVICE_ID 0xc51d1000 |
|
48 |
|
49 class DSVPHostFsDriverFactory : public DLogicalDevice |
|
50 { |
|
51 public: |
|
52 |
|
53 DSVPHostFsDriverFactory(); |
|
54 virtual TInt Install(); |
|
55 virtual void GetCaps(TDes8& aDes) const; |
|
56 virtual TInt Create(DLogicalChannelBase*& aChannel); |
|
57 }; |
|
58 |
|
59 class DSVPHostFsChannel : public DLogicalChannel |
|
60 { |
|
61 public: |
|
62 |
|
63 DSVPHostFsChannel(DLogicalDevice* aLogicalDevice); |
|
64 ~DSVPHostFsChannel(); |
|
65 |
|
66 virtual TInt DoCreate(TInt aUnit, const TDesC* anInfo, const TVersion& aVer); |
|
67 virtual void HandleMsg(TMessageBase* aMsg); |
|
68 |
|
69 protected: |
|
70 virtual void DoCancel(TInt aReqNo); |
|
71 virtual TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); |
|
72 virtual TInt DoControl(TInt aFunction, TAny *a1, TAny *a2); |
|
73 |
|
74 private: |
|
75 TInt MkDir(TSVPHostFsMkDirInfo* aInfo); |
|
76 TInt RmDir(TSVPHostFsRmDirInfo* aInfo); |
|
77 TInt Delete(TSVPHostFsDeleteInfo* aInfo); |
|
78 TInt Rename(TSVPHostFsRenameInfo* aInfo); |
|
79 TInt Replace(TSVPHostFsReplaceInfo* aInfo); |
|
80 TInt Entry(TSVPHostFsEntryInfo* aInfo); |
|
81 TInt SetEntry(TSVPHostFsSetEntryInfo* aInfo); |
|
82 TInt FileOpen(TSVPHostFsFileOpenInfo* aInfo); |
|
83 TInt FileClose(TUint32 aDrive, TUint32 aHandle); |
|
84 TInt FileRead(TSVPHostFsFileReadInfo* aInfo); |
|
85 TInt FileWrite(TSVPHostFsFileWriteInfo* aInfo); |
|
86 TInt FileSetSize(TSVPHostFsFileSetSizeInfo* aInfo); |
|
87 TInt FileSetEntry(TSVPHostFsSetEntryInfo* aInfo); |
|
88 TInt DirOpen(TSVPHostFsDirOpenInfo* aInfo); |
|
89 TInt Flush(TUint32 aDrive); |
|
90 TInt DirClose(TUint32 aDrive, TUint32 aHandle); |
|
91 TInt DirRead(TSVPHostFsDirReadInfo* aInfo); |
|
92 |
|
93 TInt GetID(TUint32 aDrive, TUint32 * aId); |
|
94 |
|
95 TInt SetUpDrives(); |
|
96 TInt GetDriveMap(TAny * aMap); |
|
97 |
|
98 private: |
|
99 DThread* iClientThread; |
|
100 TDfcQue* iDFCQue; |
|
101 TUint32 iDriveMap[DRIVE_MAP_SIZE] ; |
|
102 |
|
103 }; |
|
104 |
|
105 |
|
106 #define RET_IF_ERROR(v, e) { if ((v = (e)) != KErrNone) return v; } |
|
107 |
|
108 |
|
109 #define EDeviceID 0 |
|
110 #define EOp 1 |
|
111 #define ETreeStart 1 |
|
112 #define EResult 2 |
|
113 #define EArg0 3 |
|
114 #define EArg1 4 |
|
115 #define EArg2 5 |
|
116 #define EArg3 6 |
|
117 |
|
118 static inline TUint32 SVPReadReg(TUint32 dev, TUint32 aReg) |
|
119 { |
|
120 DP("** ReadReg @ 0x%08x (%d)",dev,aReg); |
|
121 |
|
122 return *(volatile TUint32 *)(dev + (aReg << 2)); |
|
123 } |
|
124 |
|
125 static inline void SVPWriteReg(TUint32 dev, TUint32 aReg, TUint32 aVal) |
|
126 { |
|
127 DP("** WriteReg @ 0x%08x (%d,%d)",dev,aReg,aVal); |
|
128 |
|
129 *(volatile TUint32*)(dev + (aReg << 2)) = aVal; |
|
130 } |
|
131 |
|
132 static inline void SVPInvoke(TUint32 dev, TUint32 aVal) |
|
133 { |
|
134 DP("** Invoke @ 0x%08x (%d)",dev,aVal); |
|
135 |
|
136 *(TUint32*)(dev + (EOp << 2)) = aVal; |
|
137 } |
|
138 |
|
139 ///////////////////////////////////////////////////////////////////////// |
|
140 // |
|
141 // DSVPHostFsDriverFactory |
|
142 // |
|
143 ///////////////////////////////////////////////////////////////////////// |
|
144 |
|
145 // |
|
146 // DSVPHostFsDriverFactory constructor |
|
147 // |
|
148 DSVPHostFsDriverFactory::DSVPHostFsDriverFactory() |
|
149 { |
|
150 DP("** (SVPHOSTFSDRIVER) DSVPHostFsDriverFactory::DSVPHostFsDriverFactory()"); |
|
151 |
|
152 iVersion = TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
153 } |
|
154 |
|
155 // |
|
156 // DSVPHostFsDriverFactory::Create |
|
157 // |
|
158 TInt DSVPHostFsDriverFactory::Create(DLogicalChannelBase*& aChannel) |
|
159 { |
|
160 DP("** (SVPHOSTFSDRIVER) DSVPHostFsDriverFactory::Create()"); |
|
161 |
|
162 aChannel = new DSVPHostFsChannel(this); |
|
163 |
|
164 return aChannel ? KErrNone : KErrNoMemory; |
|
165 } |
|
166 |
|
167 // |
|
168 // DSVPHostFsDriverFactory::Install |
|
169 // |
|
170 TInt DSVPHostFsDriverFactory::Install() |
|
171 { |
|
172 DP("** (SVPHOSTFSDRIVER) DSVPHostFsDriverFactory::Install()"); |
|
173 |
|
174 return(SetName(&KSVPHostFsDriverName)); |
|
175 } |
|
176 |
|
177 // |
|
178 // DSVPHostFsDriverFactory::Install |
|
179 // |
|
180 void DSVPHostFsDriverFactory::GetCaps(TDes8& aDes) const |
|
181 { |
|
182 DP("** (SVPHOSTFSDRIVER) DSVPHostFsDriverFactory::GetCaps()"); |
|
183 |
|
184 TCapsSVPHostFsDriver b; |
|
185 b.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber); |
|
186 aDes.FillZ(aDes.MaxLength()); |
|
187 aDes.Copy((TUint8 *)&b, Min(aDes.MaxLength(), sizeof(b))); |
|
188 } |
|
189 |
|
190 |
|
191 ///////////////////////////////////////////////////////////////////////// |
|
192 // |
|
193 // DSVPHostFsChannel implementation |
|
194 // |
|
195 ///////////////////////////////////////////////////////////////////////// |
|
196 |
|
197 // |
|
198 // DSVPHostFsChannel constructor |
|
199 // |
|
200 DSVPHostFsChannel::DSVPHostFsChannel(DLogicalDevice* aLogicalDevice) |
|
201 { |
|
202 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DSVPHostFsChannel()"); |
|
203 |
|
204 iDevice = aLogicalDevice; |
|
205 |
|
206 iClientThread = &Kern::CurrentThread(); |
|
207 iClientThread->Open(); |
|
208 } |
|
209 |
|
210 // |
|
211 // DSVPHostFsChannel destructor |
|
212 // |
|
213 DSVPHostFsChannel::~DSVPHostFsChannel() |
|
214 { |
|
215 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::~DSVPHostFsChannel()"); |
|
216 Kern::SafeClose((DObject*&)iClientThread, NULL); |
|
217 } |
|
218 |
|
219 // |
|
220 // DSVPHostFsChannel::DoCreate |
|
221 // |
|
222 TInt DSVPHostFsChannel::DoCreate(TInt /*aUnit*/, const TDesC* anInfo, const TVersion& aVer) |
|
223 { |
|
224 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DoCreate()"); |
|
225 |
|
226 if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer)) |
|
227 return KErrNotSupported; |
|
228 |
|
229 |
|
230 //Setup the driver for receiving client messages |
|
231 SetDfcQ(Kern::DfcQue0()); |
|
232 iMsgQ.Receive(); |
|
233 |
|
234 SetUpDrives(); |
|
235 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DoCreate()- checking device"); |
|
236 TUint id = SVPReadReg(KHwSVPHostFileSystemDevice, EDeviceID); |
|
237 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DoCreate()- checked device- 0x%08x -expected 0x%08x", |
|
238 id, SVP_HOST_FS_DEVICE_ID); |
|
239 return id == SVP_HOST_FS_DEVICE_ID ? KErrNone : KErrHardwareNotAvailable; |
|
240 } |
|
241 |
|
242 TInt DSVPHostFsChannel::SetUpDrives() |
|
243 { |
|
244 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::SetUpDrives() @ 0x%08x", KHwSVPPlatformDevice) ; |
|
245 TUint32 platId = SVPReadReg(KHwSVPPlatformDevice, EDeviceID); |
|
246 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::SetUpDrives()- checked device- 0x%08x -expected 0x%08x", |
|
247 platId, SVP_PLATFORM_DEVICE_ID); |
|
248 if (platId != SVP_PLATFORM_DEVICE_ID) return KErrHardwareNotAvailable; |
|
249 |
|
250 TUint32 * fdt = (TUint32 *)((char *)(SVPReadReg(KHwSVPPlatformDevice, ETreeStart) + KHwSVPPlatformDevice)); |
|
251 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::SetUpDrives()- device tree @ 0x%08x", fdt); |
|
252 |
|
253 // Iteratate over the tree looking for "syborg,hostfs" nodes. |
|
254 const char * compatible = "syborg,hostfs" ; |
|
255 int offset = fdt_node_offset_by_compatible(fdt, -1, compatible); |
|
256 while (offset != -FDT_ERR_NOTFOUND) |
|
257 { |
|
258 if (offset < 0) |
|
259 { |
|
260 DP("FDT: Node not found %d", offset) ; |
|
261 return KErrHardwareNotAvailable ; |
|
262 } |
|
263 |
|
264 int lenp1, lenp2 = 0; |
|
265 TUint32 * deviceAddressp = (TUint32 *)fdt_getprop(fdt,offset,"reg",&lenp1); |
|
266 |
|
267 if (!deviceAddressp) |
|
268 { |
|
269 DP("FDT format error: reg %d", lenp1); |
|
270 return KErrHardwareNotAvailable ; |
|
271 } |
|
272 |
|
273 |
|
274 TUint32 * driveNumberp = (TUint32 *)fdt_getprop(fdt,offset,"drive-number",&lenp2); |
|
275 if (!driveNumberp) |
|
276 { |
|
277 DP("FDT format error: drive-number %d", lenp2); |
|
278 return KErrHardwareNotAvailable ; |
|
279 } |
|
280 TUint32 deviceAddressPhys = bswap_32(*deviceAddressp); |
|
281 |
|
282 #define PhysicalToLinear(addr) ((addr & (~(Epoc::LinearToPhysical(KPrimaryIOBase)))) | KPrimaryIOBase) |
|
283 |
|
284 TUint32 deviceAddressLin = PhysicalToLinear(deviceAddressPhys) ; |
|
285 TUint32 driveNumber = bswap_32(*driveNumberp) ; |
|
286 DP("FDT: dev address phys 0x%08x lin 0x%08x len1 %d drive number %08x len2 %d", |
|
287 deviceAddressPhys, deviceAddressLin, lenp1, driveNumber, lenp2) ; |
|
288 TUint32 fsId = SVPReadReg(deviceAddressLin, EDeviceID) ; |
|
289 DP("FDT: dev id 0x%08x", fsId) ; |
|
290 if (fsId != SVP_HOST_FS_DEVICE_ID) return KErrHardwareNotAvailable ; |
|
291 |
|
292 // we have a disagreement about the base number of the drives: 0 or 1? |
|
293 iDriveMap[driveNumber-1] = deviceAddressLin ; |
|
294 offset = fdt_node_offset_by_compatible(fdt, offset, compatible); |
|
295 } |
|
296 return KErrNone; |
|
297 } |
|
298 |
|
299 // |
|
300 // DSVPHostFsChannel::DoCancel |
|
301 // |
|
302 void DSVPHostFsChannel::DoCancel(TInt aReqNo) |
|
303 { |
|
304 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DoCancel() %x(%d)", aReqNo, aReqNo); |
|
305 } |
|
306 |
|
307 // |
|
308 // DSVPHostFsChannel::DoRequest |
|
309 // |
|
310 TInt DSVPHostFsChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2) |
|
311 { |
|
312 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DoRequest() %x(%d)", aReqNo, aReqNo); |
|
313 |
|
314 TInt err = KErrGeneral; |
|
315 |
|
316 (void)aStatus; |
|
317 |
|
318 switch(aReqNo) |
|
319 { |
|
320 case RSVPHostFsDriver::EMkDir: |
|
321 { |
|
322 err = MkDir((TSVPHostFsMkDirInfo*)a1); |
|
323 break; |
|
324 } |
|
325 case RSVPHostFsDriver::ERmDir: |
|
326 { |
|
327 err = RmDir((TSVPHostFsRmDirInfo*)a1); |
|
328 break; |
|
329 } |
|
330 case RSVPHostFsDriver::EDelete: |
|
331 { |
|
332 err = Delete((TSVPHostFsDeleteInfo*)a1); |
|
333 break; |
|
334 } |
|
335 case RSVPHostFsDriver::ERename: |
|
336 { |
|
337 err = Rename((TSVPHostFsRenameInfo*)a1); |
|
338 break; |
|
339 } |
|
340 case RSVPHostFsDriver::EReplace: |
|
341 { |
|
342 err = Replace((TSVPHostFsReplaceInfo*)a1); |
|
343 break; |
|
344 } |
|
345 case RSVPHostFsDriver::EEntry: |
|
346 { |
|
347 err = Entry((TSVPHostFsEntryInfo*)a1); |
|
348 break; |
|
349 } |
|
350 case RSVPHostFsDriver::ESetEntry: |
|
351 { |
|
352 err = SetEntry((TSVPHostFsSetEntryInfo*)a1); |
|
353 break; |
|
354 } |
|
355 case RSVPHostFsDriver::EFileOpen: |
|
356 { |
|
357 err = FileOpen((TSVPHostFsFileOpenInfo*)a1); |
|
358 break; |
|
359 } |
|
360 case RSVPHostFsDriver::EDirOpen: |
|
361 { |
|
362 err = DirOpen((TSVPHostFsDirOpenInfo*)a1); |
|
363 break; |
|
364 } |
|
365 case RSVPHostFsDriver::EFileClose: |
|
366 { |
|
367 err = FileClose((TUint32)a1, (TUint32)a2); |
|
368 break; |
|
369 } |
|
370 case RSVPHostFsDriver::EFileRead: |
|
371 { |
|
372 err = FileRead((TSVPHostFsFileReadInfo*)a1); |
|
373 break; |
|
374 } |
|
375 case RSVPHostFsDriver::EFileWrite: |
|
376 { |
|
377 err = FileWrite((TSVPHostFsFileWriteInfo*)a1); |
|
378 break; |
|
379 } |
|
380 case RSVPHostFsDriver::EFileSetSize: |
|
381 { |
|
382 err = FileSetSize((TSVPHostFsFileSetSizeInfo*)a1); |
|
383 break; |
|
384 } |
|
385 case RSVPHostFsDriver::EFileFlushAll: |
|
386 { |
|
387 err = Flush((TUint32)a1); |
|
388 break; |
|
389 } |
|
390 case RSVPHostFsDriver::EDirClose: |
|
391 { |
|
392 err = DirClose((TUint32)a1, (TUint32)a2); |
|
393 break; |
|
394 } |
|
395 case RSVPHostFsDriver::EDirRead: |
|
396 { |
|
397 err = DirRead((TSVPHostFsDirReadInfo*)a1); |
|
398 break; |
|
399 } |
|
400 case RSVPHostFsDriver::EGetDeviceID: |
|
401 { |
|
402 err = GetID((TUint32)a1, (TUint32*)a2); |
|
403 break; |
|
404 } |
|
405 case RSVPHostFsDriver::EGetDriveMap: |
|
406 { |
|
407 err = GetDriveMap((TUint32*)a1); |
|
408 break; |
|
409 } |
|
410 |
|
411 default: |
|
412 { |
|
413 err = KErrGeneral; |
|
414 } |
|
415 } |
|
416 |
|
417 if (KErrNone != err) |
|
418 { |
|
419 DP("Error %d from DoRequest", err); |
|
420 } |
|
421 |
|
422 return err; |
|
423 } |
|
424 |
|
425 // |
|
426 // DSVPHostFsChannel::DoControl |
|
427 // |
|
428 TInt DSVPHostFsChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2) |
|
429 { |
|
430 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DoControl()"); |
|
431 |
|
432 DP("DoControl Function %d", aFunction); |
|
433 |
|
434 TInt err = KErrGeneral; |
|
435 |
|
436 /* There should be a good reason to use a control rather than a request. */ |
|
437 |
|
438 if (KErrNone != err) |
|
439 { |
|
440 DP("** (SVPHOSTFSDRIVER) Error %d from control function", err); |
|
441 } |
|
442 |
|
443 return err; |
|
444 } |
|
445 |
|
446 void DSVPHostFsChannel::HandleMsg(TMessageBase* aMsg) |
|
447 { |
|
448 |
|
449 TThreadMessage& m = *(TThreadMessage*)aMsg; |
|
450 TInt id = m.iValue; |
|
451 |
|
452 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::HandleMsg() %x(%d)", id, id); |
|
453 |
|
454 if (id == (TInt)ECloseMsg) |
|
455 { |
|
456 m.Complete(KErrNone, EFalse); |
|
457 return; |
|
458 } |
|
459 if (id == KMaxTInt) |
|
460 { |
|
461 // DoCancel |
|
462 DoCancel(m.Int0()); |
|
463 m.Complete(KErrNone, ETrue); |
|
464 return; |
|
465 } |
|
466 if (id < 0) |
|
467 { |
|
468 // DoRequest |
|
469 TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0(); |
|
470 TInt r = DoRequest(~id, pStatus, m.Ptr1(), m.Ptr2()); |
|
471 // if (r != KErrNone) |
|
472 Kern::RequestComplete(iClientThread,pStatus,r); |
|
473 m.Complete(KErrNone, ETrue); |
|
474 } |
|
475 else |
|
476 { |
|
477 // DoControl |
|
478 TInt r = DoControl(id, m.Ptr0(), m.Ptr1()); |
|
479 m.Complete(r, ETrue); |
|
480 } |
|
481 } |
|
482 |
|
483 TInt DSVPHostFsChannel::MkDir(TSVPHostFsMkDirInfo* aInfo) |
|
484 { |
|
485 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::MkDir()"); |
|
486 |
|
487 TSVPHostFsMkDirInfo info; |
|
488 TInt err = KErrNone; |
|
489 |
|
490 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsMkDirInfo))); |
|
491 |
|
492 if (!info.iName) |
|
493 return KErrArgument; |
|
494 |
|
495 TUint16 pathData[KMaxPath]; |
|
496 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iName, (TUint8*)pathData, info.iLength*2)); |
|
497 |
|
498 TUint32 device = iDriveMap[info.iDrive]; |
|
499 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)pathData)); |
|
500 SVPWriteReg(device, EArg1, info.iLength); |
|
501 SVPWriteReg(device, EArg2, info.iFlags); |
|
502 SVPInvoke(device, RSVPHostFsDriver::EMkDir); |
|
503 |
|
504 return SVPReadReg(device, EResult); |
|
505 |
|
506 } |
|
507 |
|
508 TInt DSVPHostFsChannel::RmDir(TSVPHostFsRmDirInfo* aInfo) |
|
509 { |
|
510 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::RmDir()"); |
|
511 |
|
512 TSVPHostFsRmDirInfo info; |
|
513 TInt err = KErrNone; |
|
514 |
|
515 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsRmDirInfo))); |
|
516 |
|
517 if (!info.iName) |
|
518 return KErrArgument; |
|
519 |
|
520 TUint16 pathData[KMaxPath]; |
|
521 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iName, (TUint8*)pathData, info.iLength*2)); |
|
522 |
|
523 TUint32 device = iDriveMap[info.iDrive]; |
|
524 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)pathData)); |
|
525 SVPWriteReg(device, EArg1, info.iLength); |
|
526 SVPInvoke(device, RSVPHostFsDriver::ERmDir); |
|
527 |
|
528 return SVPReadReg(device, EResult); |
|
529 |
|
530 } |
|
531 |
|
532 TInt DSVPHostFsChannel::Delete(TSVPHostFsDeleteInfo* aInfo) |
|
533 { |
|
534 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::Delete()"); |
|
535 |
|
536 TSVPHostFsDeleteInfo info; |
|
537 TInt err = KErrNone; |
|
538 |
|
539 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsDeleteInfo))); |
|
540 |
|
541 if (!info.iName) |
|
542 return KErrArgument; |
|
543 |
|
544 TUint16 pathData[KMaxPath]; |
|
545 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iName, (TUint8*)pathData, info.iLength*2)); |
|
546 |
|
547 TUint32 device = iDriveMap[info.iDrive]; |
|
548 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)pathData)); |
|
549 SVPWriteReg(device, EArg1, info.iLength); |
|
550 SVPInvoke(device, RSVPHostFsDriver::EDelete); |
|
551 |
|
552 return SVPReadReg(device, EResult); |
|
553 |
|
554 } |
|
555 |
|
556 TInt DSVPHostFsChannel::Rename(TSVPHostFsRenameInfo* aInfo) |
|
557 { |
|
558 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::Rename()"); |
|
559 |
|
560 TSVPHostFsRenameInfo info; |
|
561 TInt err = KErrNone; |
|
562 |
|
563 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsRenameInfo))); |
|
564 |
|
565 if (!info.iOldName) |
|
566 return KErrArgument; |
|
567 |
|
568 if (!info.iNewName) |
|
569 return KErrArgument; |
|
570 |
|
571 TUint16 oldPathData[KMaxPath]; |
|
572 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iOldName, (TUint8*)oldPathData, info.iOldLength*2)); |
|
573 |
|
574 TUint16 newPathData[KMaxPath]; |
|
575 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iNewName, (TUint8*)newPathData, info.iNewLength*2)); |
|
576 |
|
577 TUint32 device = iDriveMap[info.iDrive]; |
|
578 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)oldPathData)); |
|
579 SVPWriteReg(device, EArg1, info.iOldLength); |
|
580 SVPWriteReg(device, EArg2, Epoc::LinearToPhysical((TUint32)newPathData)); |
|
581 SVPWriteReg(device, EArg3, info.iNewLength); |
|
582 SVPInvoke(device, RSVPHostFsDriver::ERename); |
|
583 |
|
584 return SVPReadReg(device, EResult); |
|
585 |
|
586 } |
|
587 |
|
588 TInt DSVPHostFsChannel::Replace(TSVPHostFsReplaceInfo* aInfo) |
|
589 { |
|
590 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::Replace()"); |
|
591 |
|
592 TSVPHostFsReplaceInfo info; |
|
593 TInt err = KErrNone; |
|
594 |
|
595 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsReplaceInfo))); |
|
596 |
|
597 if (!info.iOldName) |
|
598 return KErrArgument; |
|
599 |
|
600 if (!info.iNewName) |
|
601 return KErrArgument; |
|
602 |
|
603 TUint16 oldPathData[KMaxPath]; |
|
604 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iOldName, (TUint8*)oldPathData, info.iOldLength*2)); |
|
605 |
|
606 TUint16 newPathData[KMaxPath]; |
|
607 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iNewName, (TUint8*)newPathData, info.iNewLength*2)); |
|
608 |
|
609 TUint32 device = iDriveMap[info.iDrive]; |
|
610 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)oldPathData)); |
|
611 SVPWriteReg(device, EArg1, info.iOldLength); |
|
612 SVPWriteReg(device, EArg2, Epoc::LinearToPhysical((TUint32)newPathData)); |
|
613 SVPWriteReg(device, EArg3, info.iNewLength); |
|
614 SVPInvoke(device, RSVPHostFsDriver::EReplace); |
|
615 |
|
616 return SVPReadReg(device, EResult); |
|
617 |
|
618 } |
|
619 |
|
620 TInt DSVPHostFsChannel::Entry(TSVPHostFsEntryInfo* aInfo) |
|
621 { |
|
622 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::Entry()"); |
|
623 |
|
624 TSVPHostFsEntryInfo info; |
|
625 TInt err = KErrNone; |
|
626 |
|
627 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsEntryInfo))); |
|
628 |
|
629 if (!info.iName) |
|
630 return KErrArgument; |
|
631 |
|
632 TUint16 pathData[KMaxPath]; |
|
633 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iName, (TUint8*)pathData, info.iLength*2)); |
|
634 |
|
635 TUint32 device = iDriveMap[info.iDrive]; |
|
636 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)pathData)); |
|
637 SVPWriteReg(device, EArg1, info.iLength); |
|
638 SVPInvoke(device, RSVPHostFsDriver::EEntry); |
|
639 |
|
640 RET_IF_ERROR(err, SVPReadReg(device, EResult)); |
|
641 |
|
642 TUint32 att = SVPReadReg(device, EArg0); |
|
643 TUint32 modified = SVPReadReg(device, EArg1); |
|
644 TUint32 filesize = SVPReadReg(device, EArg2); |
|
645 // TODO: Yuk! Hack alert! Say EWindows for now. But really should probably say EUnknown, |
|
646 // since the device won't tell us. Not sure if it can (easily) given remote mounting etc. |
|
647 // However this probably delays the problem. On the other hand it is probably best to make |
|
648 // the file service guess, since it need only guess once, and cache its guess. |
|
649 TUint32 filetimetype = EWindows; |
|
650 |
|
651 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iAtt, (TUint8*)&att, sizeof(att))); |
|
652 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iModified, (TUint8*)&modified, sizeof(modified))); |
|
653 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iSize, (TUint8*)&filesize, sizeof(filesize))); |
|
654 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iTimeType, (TUint8*)&filetimetype, sizeof(filetimetype))); |
|
655 return KErrNone; |
|
656 } |
|
657 |
|
658 TInt DSVPHostFsChannel::SetEntry(TSVPHostFsSetEntryInfo* aInfo) |
|
659 { |
|
660 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::SetEntry()"); |
|
661 return KErrNotSupported; |
|
662 } |
|
663 |
|
664 TInt DSVPHostFsChannel::Flush(TUint32 aDrive) |
|
665 { |
|
666 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::Flush()"); |
|
667 TUint32 device = iDriveMap[aDrive]; |
|
668 SVPInvoke(device, RSVPHostFsDriver::EFileFlushAll); |
|
669 |
|
670 return KErrNone; |
|
671 } |
|
672 |
|
673 TInt DSVPHostFsChannel::DirOpen(TSVPHostFsDirOpenInfo* aInfo) |
|
674 { |
|
675 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DirOpen()"); |
|
676 |
|
677 TSVPHostFsDirOpenInfo info; |
|
678 TInt err = KErrNone; |
|
679 |
|
680 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsDirOpenInfo))); |
|
681 |
|
682 if (!info.iName) |
|
683 return KErrArgument; |
|
684 |
|
685 TUint16 pathData[KMaxPath]; |
|
686 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iName, (TUint8*)pathData, info.iLength*2)); |
|
687 |
|
688 TUint32 device = iDriveMap[info.iDrive]; |
|
689 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)pathData)); |
|
690 SVPWriteReg(device, EArg1, info.iLength); |
|
691 SVPInvoke(device, RSVPHostFsDriver::EDirOpen); |
|
692 |
|
693 RET_IF_ERROR(err, SVPReadReg(device, EResult)); |
|
694 |
|
695 // handle is in arg 0 |
|
696 TUint32 handle = SVPReadReg(device, EArg0); |
|
697 return Kern::ThreadRawWrite(iClientThread, &aInfo->iHandle, (TUint8*)&handle, sizeof(handle)); |
|
698 } |
|
699 |
|
700 TInt DSVPHostFsChannel::FileOpen(TSVPHostFsFileOpenInfo* aInfo) |
|
701 { |
|
702 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileOpen()"); |
|
703 |
|
704 TSVPHostFsFileOpenInfo info; |
|
705 TInt err = KErrNone; |
|
706 |
|
707 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsFileOpenInfo))); |
|
708 |
|
709 if (!info.iName) |
|
710 return KErrArgument; |
|
711 |
|
712 TUint16 pathData[KMaxPath]; |
|
713 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, info.iName, (TUint8*)pathData, info.iLength*2)); |
|
714 |
|
715 TUint32 device = iDriveMap[info.iDrive]; |
|
716 SVPWriteReg(device, EArg0, Epoc::LinearToPhysical((TUint32)pathData)); |
|
717 SVPWriteReg(device, EArg1, info.iLength); |
|
718 SVPWriteReg(device, EArg2, info.iMode); |
|
719 SVPWriteReg(device, EArg3, info.iOpen); |
|
720 SVPInvoke(device, RSVPHostFsDriver::EFileOpen); |
|
721 |
|
722 RET_IF_ERROR(err, SVPReadReg(device, EResult)); |
|
723 |
|
724 TUint32 handle = SVPReadReg(device, EArg0); |
|
725 TUint32 att = SVPReadReg(device, EArg1); |
|
726 TUint32 modified = SVPReadReg(device, EArg2); |
|
727 TUint32 size = SVPReadReg(device, EArg3); |
|
728 TUint32 timeType = EWindows; |
|
729 |
|
730 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iHandle, (TUint8*)&handle, sizeof(handle))); |
|
731 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iAtt, (TUint8*)&att, sizeof(att))); |
|
732 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iModified, (TUint8*)&modified, sizeof(modified))); |
|
733 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iSize, (TUint8*)&size, sizeof(size))); |
|
734 return Kern::ThreadRawWrite(iClientThread, &aInfo->iTimeType, (TUint8*)&timeType, sizeof(timeType)); |
|
735 |
|
736 } |
|
737 |
|
738 TInt DSVPHostFsChannel::FileClose(TUint32 aDrive, TUint32 aHandle) |
|
739 { |
|
740 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileClose()"); |
|
741 |
|
742 TUint32 device = iDriveMap[aDrive]; |
|
743 SVPWriteReg(device, EArg0, aHandle); |
|
744 SVPInvoke(device, RSVPHostFsDriver::EFileClose); |
|
745 return SVPReadReg(device, EResult); |
|
746 } |
|
747 |
|
748 TInt DSVPHostFsChannel::FileRead(TSVPHostFsFileReadInfo* aInfo) |
|
749 { |
|
750 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileRead()"); |
|
751 |
|
752 char buf[0x400]; |
|
753 TSVPHostFsFileReadInfo info; |
|
754 TInt err = KErrNone; |
|
755 |
|
756 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsFileReadInfo))); |
|
757 |
|
758 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileRead handle %d length %d pos %d phys_addr 0x%08x info.iBuf 0x%08x", |
|
759 info.iHandle, info.iLength, info.iPos, Epoc::LinearToPhysical((TUint32)buf), info.iBuf); |
|
760 |
|
761 TUint32 device = iDriveMap[info.iDrive]; |
|
762 SVPWriteReg(device, EArg0, info.iHandle); |
|
763 SVPWriteReg(device, EArg1, info.iPos); |
|
764 SVPWriteReg(device, EArg2, Epoc::LinearToPhysical((TUint32)buf)); |
|
765 SVPWriteReg(device, EArg3, info.iLength); |
|
766 SVPInvoke(device, RSVPHostFsDriver::EFileRead); |
|
767 |
|
768 RET_IF_ERROR(err, SVPReadReg(device, EResult)); |
|
769 |
|
770 TUint32 len = SVPReadReg(device, EArg0); |
|
771 |
|
772 DP("** (SVPHOSTFSDRIVER) Read %d bytes", len); |
|
773 |
|
774 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iLength, (TUint8*)&len, sizeof(len))); |
|
775 return Kern::ThreadRawWrite(iClientThread, (TUint8*)info.iBuf, (TUint8*)&buf, len); |
|
776 } |
|
777 |
|
778 TInt DSVPHostFsChannel::FileWrite(TSVPHostFsFileWriteInfo* aInfo) |
|
779 { |
|
780 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileWrite()"); |
|
781 |
|
782 char buf[0x400]; |
|
783 TSVPHostFsFileWriteInfo info; |
|
784 TInt err = KErrNone; |
|
785 |
|
786 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsFileWriteInfo))); |
|
787 |
|
788 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileWrite handle %d length %d pos %d phys_addr 0x%08x info.iBuf 0x%08x", |
|
789 info.iHandle, info.iLength, info.iPos, Epoc::LinearToPhysical((TUint32)buf), info.iBuf); |
|
790 |
|
791 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, (TUint8 *)info.iBuf, buf, info.iLength)); |
|
792 |
|
793 TUint32 device = iDriveMap[info.iDrive]; |
|
794 SVPWriteReg(device, EArg0, info.iHandle); |
|
795 SVPWriteReg(device, EArg1, info.iPos); |
|
796 SVPWriteReg(device, EArg2, Epoc::LinearToPhysical((TUint32)buf)); |
|
797 SVPWriteReg(device, EArg3, info.iLength); |
|
798 SVPInvoke(device, RSVPHostFsDriver::EFileWrite); |
|
799 |
|
800 RET_IF_ERROR(err, SVPReadReg(device, EResult)); |
|
801 |
|
802 TUint32 len = SVPReadReg(device, EArg0); |
|
803 |
|
804 DP("** (SVPHOSTFSDRIVER) Wrote %d bytes", len); |
|
805 |
|
806 return Kern::ThreadRawWrite(iClientThread, &aInfo->iLength, (TUint8*)&len, sizeof(len)); |
|
807 } |
|
808 |
|
809 TInt DSVPHostFsChannel::FileSetSize(TSVPHostFsFileSetSizeInfo* aInfo) |
|
810 { |
|
811 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileSetSize()"); |
|
812 |
|
813 TSVPHostFsFileSetSizeInfo info; |
|
814 TInt err = KErrNone; |
|
815 |
|
816 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsFileSetSizeInfo))); |
|
817 |
|
818 TUint32 device = iDriveMap[info.iDrive]; |
|
819 SVPWriteReg(device, EArg0, info.iHandle); |
|
820 SVPWriteReg(device, EArg1, info.iLength); |
|
821 SVPInvoke(device, RSVPHostFsDriver::EFileSetSize); |
|
822 |
|
823 TUint32 res = SVPReadReg(device, EResult); |
|
824 |
|
825 RET_IF_ERROR(err, res); |
|
826 |
|
827 return res; |
|
828 } |
|
829 |
|
830 TInt DSVPHostFsChannel::FileSetEntry(TSVPHostFsSetEntryInfo* aInfo) |
|
831 { |
|
832 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileSetEntry()"); |
|
833 |
|
834 return KErrNotSupported; |
|
835 } |
|
836 |
|
837 TInt DSVPHostFsChannel::DirClose(TUint32 aDrive, TUint32 aHandle) |
|
838 { |
|
839 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DirClose()"); |
|
840 |
|
841 TUint32 device = iDriveMap[aDrive]; |
|
842 SVPWriteReg(device, EArg0, aHandle); |
|
843 SVPInvoke(device, RSVPHostFsDriver::EDirClose); |
|
844 return SVPReadReg(device, EResult); |
|
845 } |
|
846 |
|
847 TInt DSVPHostFsChannel::DirRead(TSVPHostFsDirReadInfo* aInfo) |
|
848 { |
|
849 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::DirRead()"); |
|
850 |
|
851 TUint16 name[KMaxPath]; |
|
852 TSVPHostFsDirReadInfo info; |
|
853 TInt err = KErrNone; |
|
854 |
|
855 RET_IF_ERROR(err, Kern::ThreadRawRead(iClientThread, aInfo, (TUint8*)&info, sizeof(TSVPHostFsDirReadInfo))); |
|
856 |
|
857 |
|
858 TUint32 device = iDriveMap[info.iDrive]; |
|
859 SVPWriteReg(device, EArg0, info.iHandle); |
|
860 SVPWriteReg(device, EArg1, Epoc::LinearToPhysical((TUint32)name)); |
|
861 SVPWriteReg(device, EArg2, KMaxPath); |
|
862 SVPInvoke(device, RSVPHostFsDriver::EDirRead); |
|
863 |
|
864 RET_IF_ERROR(err, SVPReadReg(device, EResult)); |
|
865 |
|
866 TUint32 att = SVPReadReg(device, EArg0); |
|
867 TUint32 modified = SVPReadReg(device, EArg1); |
|
868 TUint32 filesize = SVPReadReg(device, EArg2); |
|
869 TUint32 namesize = SVPReadReg(device, EArg3); |
|
870 // TODO: Yuk! Hack alert! Say EWindows for now. But really should probably say EUnknown, |
|
871 // since the device won't tell us. Not sure if it can (easily) given remote mounting etc. |
|
872 // However this probably delays the problem. On the other hand it is probably best to make |
|
873 // the file service guess, since it need only guess once, and cache its guess. |
|
874 TUint32 filetimetype = EWindows; |
|
875 |
|
876 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iAtt, (TUint8*)&att, sizeof(att))); |
|
877 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iModified, (TUint8*)&modified, sizeof(modified))); |
|
878 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iSize, (TUint8*)&filesize, sizeof(filesize))); |
|
879 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iTimeType, (TUint8*)&filetimetype, sizeof(filetimetype))); |
|
880 RET_IF_ERROR(err, Kern::ThreadRawWrite(iClientThread, &aInfo->iLength, (TUint8*)&namesize, sizeof(namesize))); |
|
881 return Kern::ThreadRawWrite(iClientThread, &aInfo->iName, (TUint8*)&name, namesize * sizeof(TUint16)); |
|
882 } |
|
883 |
|
884 TInt DSVPHostFsChannel::GetID(TUint32 aDrive, TUint32 * aId) |
|
885 { |
|
886 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::GetID"); |
|
887 TUint32 device = iDriveMap[aDrive]; |
|
888 TUint32 id = SVPReadReg(device, EDeviceID); |
|
889 return Kern::ThreadRawWrite(iClientThread, aId, &id, sizeof(TUint32)); |
|
890 } |
|
891 |
|
892 TInt DSVPHostFsChannel::GetDriveMap(TAny * aMap) |
|
893 { |
|
894 DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::GetDriveMap"); |
|
895 return Kern::ThreadRawWrite(iClientThread, aMap, iDriveMap, sizeof(iDriveMap)); |
|
896 } |
|
897 |
|
898 DECLARE_EXTENSION_LDD() |
|
899 { |
|
900 DP("** (SVPHOSTFSDRIVER) DSVPHostFsDriverFactory created"); |
|
901 return new DSVPHostFsDriverFactory; |
|
902 } |
|
903 |
|
904 DECLARE_STANDARD_EXTENSION() |
|
905 { |
|
906 DP("** (SVPHOSTFSDRIVER) SVPHostFs extension entry point"); |
|
907 |
|
908 DP("** (SVPHOSTFSDRIVER) Creating LocDrv device"); |
|
909 TInt r; |
|
910 DSVPHostFsDriverFactory* device = new DSVPHostFsDriverFactory; |
|
911 if (device==NULL) |
|
912 r=KErrNoMemory; |
|
913 else |
|
914 r=Kern::InstallLogicalDevice(device); |
|
915 |
|
916 DP("** (SVPHOSTFSDRIVER) Installing LocDrv device in kernel returned %d",r); |
|
917 |
|
918 return r; |
|
919 } |