os/kernelhwsrv/kerneltest/f32test/shostmassstorage/msman/src/cusbmsmountmanager.cpp
Update contrib.
1 // Copyright (c) 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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include <d32usbdi_hubdriver.h>
20 #include <d32usbdescriptors.h>
21 #include <d32usbtransfers.h>
25 #include "rusbhostmsdevice.h"
27 #include "rextfilesystem.h"
29 #include "cusbmsmountmanager.h"
34 CDevice* CDevice::NewL()
37 CDevice* r = new (ELeave) CDevice();
38 CleanupStack::PushL(r);
46 void CDevice::ConstructL()
61 __USBHOSTPRINT1(_L("~CDevice Token=%d"), iDeviceToken);
65 TToken CDevice::OpenDeviceL(TUint aDeviceHandle, RUsbHubDriver& aHub)
68 __USBHOSTPRINT1(_L("CDevice::OpenDeviceL Handle=%d"), aDeviceHandle);
70 TInt err = iUsbDevice.Open(aHub, aDeviceHandle);
71 __USBHOSTPRINT1(_L(" - returned %d\n"), err);
72 User::LeaveIfError(err);
74 /* Retrieve the device descriptor */
75 TUsbDeviceDescriptor devDescriptor;
76 User::LeaveIfError(iUsbDevice.GetDeviceDescriptor(devDescriptor));
77 iUsbPrint.PrintDescriptor(devDescriptor, 0, &iUsbDevice);
79 iUsbPrint.PrintTree(devDescriptor);
81 /* Retrieve the configuration descriptor */
82 TUsbConfigurationDescriptor configDescriptor;
83 User::LeaveIfError(iUsbDevice.GetConfigurationDescriptor(configDescriptor));
84 iUsbPrint.PrintDescriptor(configDescriptor, 0, &iUsbDevice);
86 /* Get the token for interface 0 */
88 err = iUsbDevice.GetTokenForInterface(0, token);
89 __USBHOSTPRINT2(_L("RUsbDevice::GetTokenForInterface returned error %d, token %08x"), err, token);
90 User::LeaveIfError(err);
92 /* open the interface */
93 RUsbInterface interface_ep0;
94 err = interface_ep0.Open(token);
95 __USBHOSTPRINT1(_L("RUsbInterface::Open returned error %d"), err);
96 User::LeaveIfError(err);
98 /* Retrieve the interface and device descriptors */
99 TUsbInterfaceDescriptor ifDescriptor;
100 User::LeaveIfError(interface_ep0.GetInterfaceDescriptor(ifDescriptor));
101 iUsbPrint.PrintDescriptor(ifDescriptor);
103 if (!IsDeviceMassStorage(ifDescriptor, devDescriptor))
105 RDebug::Print(_L("ATTACHED DEVICE IS NOT A MASS STORAGE DEVICE!\n"));
106 User::Leave(KErrGeneral);
109 TUint8 iProtocolId = ifDescriptor.InterfaceSubClass();
110 TUint8 iTransportId = ifDescriptor.InterfaceProtocol();
112 interface_ep0.Close();
114 THostMassStorageConfig msConfig;
115 msConfig.iInterfaceToken = token;
116 msConfig.iProtocolId =iProtocolId;
117 msConfig.iTransportId = iTransportId;
118 msConfig.iStatusPollingInterval = 10; // 10 secs
122 TRequestStatus status;
123 iUsbHostMsDevice.Add(msConfig, status);
124 User::WaitForRequest(status);
125 if (status.Int() != KErrNone)
127 __USBHOSTPRINT(_L("Add device failed"));
128 User::Leave(status.Int());
130 TInt r = iUsbHostMsDevice.GetNumLun(numLun);
133 __USBHOSTPRINT(_L("GetNumLun failed"));
137 if (numLun > KMaxLun)
139 __USBHOSTPRINT1(_L("Device MaxLun = %d. Error MaxLun > MAXLUN !"), numLun);
140 User::Leave(KErrGeneral);
143 __USBHOSTPRINT1(_L("MSC registered with %d Luns"), numLun);
145 iDeviceToken = token;
147 iDeviceHandle = aDeviceHandle;
152 void CDevice::CloseDeviceL()
156 THostMassStorageConfig msConfig;
157 msConfig.iInterfaceToken = iDeviceToken;
159 iUsbHostMsDevice.Remove();
164 void CDevice::MountLogicalUnitsL()
169 for (TInt lun = 0; lun < iNumLuns; lun++)
171 TDriveNumber driveNumber = iExt.GetDriveL();
172 __PRINT2(_L("Mounting drive=%d lun=%d..."), driveNumber, lun);
173 RDebug::Print(_L("Mounting drive=%d lun=%d..."), driveNumber, lun);
174 TRAPD(err, iExt.MountL(iUsbHostMsDevice, driveNumber, iDeviceToken, lun));
175 if (err == KErrNone || err == KErrNotReady || err == KErrCorrupt)
177 iLuList.Append(driveNumber);
179 __PRINT1(_L("%d"), err);
180 RDebug::Print(_L("err=%d"), err);
185 void CDevice::DismountLogicalUnitsL()
188 for (TInt lun = 0; lun < iLuList.Count(); lun++)
190 TDriveNumber driveNumber = iLuList[lun];
191 iExt.DismountL(iUsbHostMsDevice, driveNumber);
199 TInt CDevice::GetEndpointAddress(RUsbInterface& aUsbInterface,
200 TInt aInterfaceSetting,
201 TUint8 aTransferType,
203 TInt& aEndpointAddress) const
207 // Get the interface descriptor
208 RDebug::Print(_L("GetEndpointAddress : Getting the interface descriptor for this alternate setting"));
210 TUsbInterfaceDescriptor alternateInterfaceDescriptor;
211 TInt err = aUsbInterface.GetAlternateInterfaceDescriptor(aInterfaceSetting, alternateInterfaceDescriptor);
215 RDebug::Print(_L("GetEndpointAddress : <Error %d> Unable to get alternate interface (%d) descriptor"),err,aInterfaceSetting);
219 // Parse the descriptor tree from the interface
220 RDebug::Print(_L("Search the child descriptors for matching endpoint attributes"));
222 TUsbGenericDescriptor* descriptor = alternateInterfaceDescriptor.iFirstChild;
226 RDebug::Print(_L("GetEndpointAddress : Check descriptor type for endpoint"));
228 // Cast the descriptor to an endpoint descriptor
229 TUsbEndpointDescriptor* endpoint = TUsbEndpointDescriptor::Cast(descriptor);
233 RDebug::Print(_L("GetEndpointAddress : Match attributes for transfer type"));
235 if ( (endpoint->Attributes() & aTransferType) == aTransferType)
237 RDebug::Print(_L("GetEndpointAddress : Match attributes for endpoint direction"));
239 if ( (endpoint->EndpointAddress() & 0x80) == aDirection)
241 aEndpointAddress = endpoint->EndpointAddress();
242 RDebug::Print(_L("GetEndpointAddress : Endpoint address found"));
248 descriptor = descriptor->iNextPeer;
251 // Unable to find the endpoint address
252 RDebug::Print(_L("GetEndpointAddress : Unable to find endpoint address matching the specified attributes"));
258 TBool CDevice::IsDeviceMassStorage(const TUsbInterfaceDescriptor& aInterfaceDesc,
259 const TUsbDeviceDescriptor& aDeviceDesc) const
262 /* check the interface descriptor */
263 if(aInterfaceDesc.InterfaceClass() == 0x08 &&
264 aInterfaceDesc.InterfaceSubClass() == 0x06 &&
265 aInterfaceDesc.InterfaceProtocol() == 0x50)
267 if(aDeviceDesc.DeviceClass() == 0x00 &&
268 aDeviceDesc.DeviceSubClass() == 0x00 &&
269 aDeviceDesc.DeviceProtocol() == 0x00)
278 TLun CDevice::DriveMap(TDriveMap& aDriveMap) const
281 TDriveNumber driveNumber;
282 RDebug::Printf("LuList.Count=%d", iLuList.Count());
283 for (TInt i = 0; i < iLuList.Count(); i++)
285 driveNumber = iLuList[i];
286 aDriveMap[driveNumber] = iDeviceToken;
287 RDebug::Printf("Device %d token=%d driveNumber=%d", i, iDeviceToken, driveNumber);
294 TLun CDevice::DeviceMap(TDeviceMap& aDeviceMap) const
297 TDriveNumber driveNumber;
298 RDebug::Printf("LuList.Count=%d", iLuList.Count());
299 for (TInt i = 0; i < iLuList.Count(); i++)
301 driveNumber = iLuList[i];
302 aDeviceMap[i] = driveNumber;
303 RDebug::Printf("CDevice LUN=%d driveNumber=%d", i, driveNumber);
310 CUsbMsMountManager* CUsbMsMountManager::NewL()
313 CUsbMsMountManager* r = new (ELeave) CUsbMsMountManager();
314 CleanupStack::PushL(r);
322 void CUsbMsMountManager::ConstructL()
328 CUsbMsMountManager::CUsbMsMountManager()
334 CUsbMsMountManager::~CUsbMsMountManager()
337 iDeviceList.ResetAndDestroy();
341 // adds new entry for this device
342 void CUsbMsMountManager::AddDeviceL(CDevice* aDevice)
345 iDeviceList.Append(aDevice);
349 CDevice* CUsbMsMountManager::RemoveDeviceL(TUint aDeviceHandle)
352 TInt index = GetHandleIndexL(aDeviceHandle);
353 CDevice* device = iDeviceList[index];
354 iDeviceList.Remove(index);
358 void CUsbMsMountManager::CloseAllDevicesL()
361 for (TInt i = 0; i < iDeviceList.Count(); i++)
363 iDeviceList[i]->CloseDeviceL();
368 TInt CUsbMsMountManager::GetDeviceIndexL(TToken aDeviceToken) const
372 for (index = 0; index < iDeviceList.Count(); index++)
374 if (aDeviceToken == iDeviceList[index]->DeviceToken())
380 if (index == iDeviceList.Count())
382 User::Leave(KErrNotFound);
389 TInt CUsbMsMountManager::GetHandleIndexL(TUint aDeviceHandle) const
393 for (index = 0; index < iDeviceList.Count(); index++)
395 if (aDeviceHandle == iDeviceList[index]->DeviceHandle())
401 if (index == iDeviceList.Count())
403 User::Leave(KErrNotFound);
411 // mounts all LUNs for the device
412 void CUsbMsMountManager::MountDeviceL(TUint aDeviceHandle)
415 TInt index = GetHandleIndexL(aDeviceHandle);
416 iDeviceList[index]->MountLogicalUnitsL();
421 // dismount all LUNs for this device
422 void CUsbMsMountManager::DismountDeviceL(TUint aDeviceHandle)
425 TInt index = GetHandleIndexL(aDeviceHandle);
426 iDeviceList[index]->DismountLogicalUnitsL();
431 void CUsbMsMountManager::DismountL()
434 for (TInt i = 0; i < iDeviceList.Count(); i++)
436 iDeviceList[i]->DismountLogicalUnitsL();
441 void CUsbMsMountManager::DriveMap(TDriveMap& aDriveMap) const
445 RDebug::Printf("DeviceList.Count=%d", iDeviceList.Count());
446 for (TInt i = 0; i < iDeviceList.Count(); i++)
448 maxLun = iDeviceList[i]->DriveMap(aDriveMap);
449 RDebug::Printf("%d %d", i, maxLun);
454 void CUsbMsMountManager::DeviceMap(TInt aDeviceIndex, TDeviceMap& aDeviceMap) const
457 RDebug::Printf("Device=%d", aDeviceIndex);
459 __ASSERT_DEBUG(aDeviceIndex < iDeviceList.Count(), User::Invariant());
460 iDeviceList[aDeviceIndex]->DeviceMap(aDeviceMap);
465 TUsbPrint::TUsbPrint()
470 void TUsbPrint::PrintTree(const TUsbGenericDescriptor& aDesc, TInt aDepth)
478 for(TInt depth=aDepth;depth>=0;--depth)
482 if(aDesc.iRecognisedAndParsed == TUsbGenericDescriptor::ERecognised)
484 RDebug::Print(_L("%S+0x%08x - %d 0x%02x"), &buf, &aDesc, aDesc.ibLength, aDesc.ibDescriptorType);
488 RDebug::Print(_L("%S-0x%08x - %d 0x%02x"), &buf, &aDesc, aDesc.ibLength, aDesc.ibDescriptorType);
490 HBufC* blob = HBufC::New(5*aDesc.iBlob.Length()); // 5* for " 0x" + 2*bytes for hex representation
493 for(TInt i=0;i<aDesc.iBlob.Length();++i)
495 blob->Des().AppendFormat(_L("0x%02x "), aDesc.iBlob[i]);
497 RDebug::Print(_L("%S >%S"), &buf, blob);
500 if(aDesc.iFirstChild)
502 RDebug::Print(_L("%S \\ "), &buf);
503 PrintTree(*(aDesc.iFirstChild), aDepth+1);
504 RDebug::Print(_L("%S / "), &buf);
508 PrintTree(*(aDesc.iNextPeer), aDepth);
513 static TUint16 gLangId = 0x0000;
515 void TUsbPrint::SetLanguageToPrintL(RUsbDevice& aDevice)
519 // Try to set language to US Eng, otherwise take the first one listed.
520 if(gLangId == 0x0000) // Only make the request if not been made before.
522 // Get string descriptor 0.
523 TBuf8<256> stringBuf;
524 TUsbStringDescriptor* stringDesc = NULL;
525 User::LeaveIfError(aDevice.GetStringDescriptor(stringDesc, stringBuf, 0));
526 CleanupStack::PushL(*stringDesc);
528 // Search for US English
529 TBool usEngLang = EFalse;
532 const TUint16 KLangIdUsEng = 0x0409;
533 while(!usEngLang && langId != KErrNotFound)
535 langId = stringDesc->GetLangId(index);
536 usEngLang = (langId == KLangIdUsEng);
540 // Set the language appropriately
543 gLangId = KLangIdUsEng;
547 gLangId = stringDesc->GetLangId(0);
550 CleanupStack::PopAndDestroy(); // stringDesc
555 void TUsbPrint::PrintStringFromIndex(const TDesC& aFormatString,
561 // If we have no device handle, we cannot go and get any strings.
562 // If we have index 0, this indicates we don't have a string for this entry.
563 if(aDevice && aIndex != 0)
565 TRAPD(err, SetLanguageToPrintL(*aDevice));
568 TBuf8<255> stringBuf;
569 TUsbStringDescriptor* stringDesc = NULL;
570 err = aDevice->GetStringDescriptor(stringDesc, stringBuf, aIndex, gLangId);
574 stringDesc->StringData(buf);
575 RDebug::Print(aFormatString, &buf);
576 stringDesc->DestroyTree();
582 RDebug::Print(_L("Error while Selecting Langauge %d\n"), err);
588 void TUsbPrint::PrintDescriptor(const TUsbDeviceDescriptor& aDeviceDesc,
594 RDebug::Print(_L("USBBcd = 0x%04x\n"), aDeviceDesc.USBBcd());
595 RDebug::Print(_L("DeviceClass = 0x%02x\n"), aDeviceDesc.DeviceClass());
596 RDebug::Print(_L("DeviceSubClass = 0x%02x\n"), aDeviceDesc.DeviceSubClass());
597 RDebug::Print(_L("DeviceProtocol = 0x%02x\n"), aDeviceDesc.DeviceProtocol());
598 RDebug::Print(_L("MaxPacketSize0 = 0x%02x\n"), aDeviceDesc.MaxPacketSize0());
599 RDebug::Print(_L("VendorId = 0x%04x\n"), aDeviceDesc.VendorId());
600 RDebug::Print(_L("ProductId = 0x%04x\n"), aDeviceDesc.ProductId());
601 RDebug::Print(_L("DeviceBcd = 0x%04x\n"), aDeviceDesc.DeviceBcd());
602 RDebug::Print(_L("ManufacturerIndex = 0x%02x\n"), aDeviceDesc.ManufacturerIndex());
603 PrintStringFromIndex(_L("ManufacturerString = %S\n"), aDeviceDesc.ManufacturerIndex(), aDevice);
604 RDebug::Print(_L("ProductIndex = 0x%02x\n"), aDeviceDesc.ProductIndex());
605 PrintStringFromIndex(_L("ProductString = %S\n"), aDeviceDesc.ProductIndex(), aDevice);
606 RDebug::Print(_L("SerialNumberIndex = 0x%02x\n"), aDeviceDesc.SerialNumberIndex());
607 PrintStringFromIndex(_L("SerialNumberString = %S\n"), aDeviceDesc.SerialNumberIndex(), aDevice);
608 RDebug::Print(_L("NumConfigurations = 0x%02x\n"), aDeviceDesc.NumConfigurations());
612 void TUsbPrint::PrintDescriptor(const TUsbConfigurationDescriptor& aConfigDesc,
617 RDebug::Print(_L("TotalLength = 0x%04x\n"), aConfigDesc.TotalLength());
618 RDebug::Print(_L("NumInterfaces = 0x%02x\n"), aConfigDesc.NumInterfaces());
619 RDebug::Print(_L("ConfigurationValue = 0x%02x\n"), aConfigDesc.ConfigurationValue());
620 RDebug::Print(_L("ConfigurationIndex = 0x%02x\n"), aConfigDesc.ConfigurationIndex());
621 PrintStringFromIndex(_L("ConfigurationString = %S\n"), aConfigDesc.ConfigurationIndex(), aDevice);
622 RDebug::Print(_L("Attributes = 0x%02x\n"), aConfigDesc.Attributes());
623 RDebug::Print(_L("MaxPower = 0x%02x\n"), aConfigDesc.MaxPower());
627 void TUsbPrint::PrintDescriptor(const TUsbEndpointDescriptor& aEndpointDesc,
629 RUsbDevice* /*aDevice*/)
632 RDebug::Print(_L("EndpointAddress = 0x%02x\n"), aEndpointDesc.EndpointAddress());
633 RDebug::Print(_L("Attributes = 0x%02x\n"), aEndpointDesc.Attributes());
634 RDebug::Print(_L("MaxPacketSize = 0x%04x\n"), aEndpointDesc.MaxPacketSize());
635 RDebug::Print(_L("Interval = 0x%02x\n"), aEndpointDesc.Interval());
639 void TUsbPrint::PrintDescriptor(const TUsbInterfaceDescriptor& aInterfaceDesc,
641 RUsbDevice* /*aDevice*/)
644 RDebug::Print(_L("InterfaceNumber = 0x%02x\n"), aInterfaceDesc.InterfaceNumber());
645 RDebug::Print(_L("AlternateSetting = 0x%02x\n"), aInterfaceDesc.AlternateSetting());
646 RDebug::Print(_L("NumEndpoints = 0x%02x\n"), aInterfaceDesc.NumEndpoints());
647 RDebug::Print(_L("InterfaceClass = 0x%02x\n"), aInterfaceDesc.InterfaceClass());
648 RDebug::Print(_L("InterfaceSubClass = 0x%02x\n"), aInterfaceDesc.InterfaceSubClass());
649 RDebug::Print(_L("InterfaceProtocol = 0x%02x\n"), aInterfaceDesc.InterfaceProtocol());
650 RDebug::Print(_L("Interface = 0x%02x\n"), aInterfaceDesc.Interface());
654 void TUsbPrint::PrintDescriptor(const TUsbStringDescriptor& aStringDesc,
656 RUsbDevice* /*aDevice*/)
661 RDebug::Print(_L("String Descriptor Zero\n"));
664 while((langId = aStringDesc.GetLangId(index)) != KErrNotFound)
666 RDebug::Print(_L(" >0x%04x\n"), langId);
672 RDebug::Print(_L("Generic String Descriptor\n"));
673 HBufC16* string = HBufC16::New(128);
676 TPtr16 stringPtr = string->Des();
677 aStringDesc.StringData(stringPtr);
678 RDebug::Print(_L(" >%S\n"), string);