os/kernelhwsrv/userlibandfileserver/fileserver/smassstorage/cbulkonlytransport.cpp
First public contribution.
1 // Copyright (c) 2004-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.
20 #include "cbulkonlytransport.h"
21 #include "cbulkonlytransportusbcldd.h"
22 #include "cbulkonlytransportusbcscldd.h"
23 #include "usbmsshared.h"
24 #include "massstoragedebug.h"
25 #include "cusbmassstorageserver.h"
29 LOCAL_D const TInt KCbwSignatureOffset = 0;
30 LOCAL_D const TInt KCbwTagOffset = 4;
31 LOCAL_D const TInt KCbwDataTransferLengthOffset = 8;
32 LOCAL_D const TInt KCbwFlagOffset = 12;
33 LOCAL_D const TInt KCbwLunOffset = 13;
34 LOCAL_D const TInt KCbwCbLengthOffset = 14;
36 LOCAL_D const TInt KMaxCbwcbLength = 16;
39 LOCAL_D const TInt KCswSingnatureOffset = 0;
40 LOCAL_D const TInt KCswTagOffset = 4;
41 LOCAL_D const TInt KCswDataResidueOffset = 8;
42 LOCAL_D const TInt KCswStatusOffset = 12;
47 This function unpacks into the TUsbRequestHdr class from a descriptor with
48 the alignment that would be introduced on the USB bus.
50 @param aBuffer Input buffer
51 @param aTarget Unpacked header.
54 TInt TUsbRequestHdr::Decode(const TDesC8& aBuffer)
57 if (aBuffer.Length() < static_cast<TInt>(KRequestHdrSize))
59 __PRINT1(_L("TUsbRequestHdr::Decode buffer invalid length %d"), aBuffer.Length());
63 iRequestType = aBuffer[0];
64 iRequest = static_cast<TEp0Request>(aBuffer[1]);
65 iValue = static_cast<TUint16>(aBuffer[2] + (aBuffer[3] << 8));
66 iIndex = static_cast<TUint16>(aBuffer[4] + (aBuffer[5] << 8));
67 iLength = static_cast<TUint16>(aBuffer[6] + (aBuffer[7] << 8));
68 __PRINT5(_L("type=%d request=%d value=%d index=%d length=%d"), iRequestType,iRequest,iValue,iIndex,iLength);
75 This function determines whether data is required by the host in response
78 @return TBool Flag indicating whether a data response required.
80 TBool TUsbRequestHdr::IsDataResponseRequired() const
83 return (iRequestType & 0x80) ? (TBool)ETrue : (TBool)EFalse;
86 //-------------------------------------
88 Create an object of a class derived from CBulkOnlyTransport (default to CBulkOnlyTransportUsbcLdd object)
89 @param aNumDrives - The number of drives available for MS
90 @param aController - reference to the parent
91 @return pointer to newly created derived class object
93 CBulkOnlyTransport* CBulkOnlyTransport::NewL(TInt aNumDrives,CUsbMassStorageController& aController)
95 __FNLOG("CBulkOnlyTransport::NewL()");
97 return NewL(aNumDrives,aController, (CUsbMassStorageController::TTransportldd) 1);
101 Create an object of a class derived from CBulkOnlyTransport
102 @param aNumDrives - The number of drives available for MS
103 @param aController - reference to the parent
104 @param aTransportLddFlag - Type of usb client ldd
105 @return pointer to newly created derived class object
107 CBulkOnlyTransport* CBulkOnlyTransport::NewL(TInt aNumDrives,CUsbMassStorageController& aController, CUsbMassStorageController::TTransportldd aTransportLddFlag)
109 __FNLOG("CBulkOnlyTransport::NewL()");
111 if (aNumDrives <=0 || static_cast<TUint>(aNumDrives) > KUsbMsMaxDrives)
113 User::Leave(KErrArgument);
116 CBulkOnlyTransportUsbcScLdd* scTransport;
117 CBulkOnlyTransportUsbcLdd* nonscTransport;
118 switch (aTransportLddFlag)
121 nonscTransport = new(ELeave) CBulkOnlyTransportUsbcLdd(aNumDrives, aController);
122 return nonscTransport;
125 scTransport = new(ELeave) CBulkOnlyTransportUsbcScLdd(aNumDrives, aController);
134 TInt CBulkOnlyTransport::InitialiseTransportL(TInt aTransportLddFlag)
136 __FNLOG("CBulkOnlyTransportUsbcScLdd::InitialiseTransportL()");
138 MTransportBase* transport;
139 iController.GetTransport(transport);
140 switch (aTransportLddFlag)
143 ret = ((CBulkOnlyTransportUsbcScLdd*) transport)->Ldd().Open(0);
150 ((CBulkOnlyTransportUsbcScLdd*) transport)->Ldd().Close();
151 CleanupStack::PushL(transport);
152 ((CBulkOnlyTransportUsbcScLdd*) transport)->ConstructL();
153 CleanupStack::Pop(transport);
157 ret = ((CBulkOnlyTransportUsbcLdd*) transport)->Ldd().Open(0);
164 ((CBulkOnlyTransportUsbcLdd*) transport)->Ldd().Close();
165 CleanupStack::PushL(transport);
166 ((CBulkOnlyTransportUsbcLdd*) transport)->ConstructL();
167 CleanupStack::Pop(transport);
177 @param aNumDrives - The number of drives available for MS
178 @param aController - reference to the parent
180 CBulkOnlyTransport::CBulkOnlyTransport(TInt aNumDrives,CUsbMassStorageController& aController):
181 CActive(EPriorityStandard),
182 iMaxLun(aNumDrives-1),
183 iController(aController),
184 iStallAllowed(ETrue),
185 iInterfaceConfigured(EFalse),
186 iCommandBufPtr(NULL,0),
189 iPaddingBufPtr(NULL,0),
190 iWriteBufPtr(NULL,0),
191 iReadBufPtr(NULL, 0),
194 __FNLOG("CBulkOnlyTransport::CBulkOnlyTransport");
200 CBulkOnlyTransport::~CBulkOnlyTransport()
202 __FNLOG("CBulkOnlyTransport::~CBulkOnlyTransport");
203 if (iInterfaceConfigured)
211 Called by the protocol after processing the packet to indicate that more data is required.
213 @param aData reference to the data buffer.
215 void CBulkOnlyTransport::SetupReadData(TUint aLength)
217 __FNLOG("CBulkOnlyTransport::SetupReadData");
218 __PRINT1(_L("Length = %d (bytes)\n"), aLength);
225 Called by the protocol after processing the packet to indicate that data should be written to the host.
227 @param aData reference to the data buffer.
229 void CBulkOnlyTransport::SetupWriteData(TPtrC8& aData)
231 __FNLOG("CBulkOnlyTransport::SetupWriteData");
232 __PRINT1(_L("Length = %d (bytes)\n"), aData.Length());
233 iWriteBufPtr.Set(aData);
238 TInt CBulkOnlyTransport::Start()
240 __FNLOG("CBulkOnlyTransport::Start");
246 return KErrBadHandle; //protocol should be set up before start
251 __PRINT(_L("CBulkOnlyTransport::Start - active before start!\n"));
255 if ((err = SetupConfigurationDescriptor()) != KErrNone ||
256 (err = SetupInterfaceDescriptors()) != KErrNone )
258 __PRINT(_L("CBulkOnlyTransport::Start - Error during descriptors setup!\n"));
262 AllocateEndpointResources();
263 ActivateDeviceStateNotifier(); // activate notifier wich will wait until USB became configured
264 TUsbcDeviceState deviceStatus = EUsbcDeviceStateDefault;
265 err = GetDeviceStatus(deviceStatus);
266 __PRINT1(_L("CBulkOnlyTransport::Start - Device status = %d\n"), deviceStatus);
267 if (err == KErrNone && deviceStatus == EUsbcDeviceStateConfigured)
269 __PRINT(_L("CBulkOnlyTransport::Start - Starting bulk only transport\n"));
273 #ifdef MSDC_MULTITHREADED
276 GetBufferPointers(aDes1, aDes2);
277 iProtocol->InitializeBufferPointers(aDes1, aDes2); // have to pass pointer to memory not offsets to initialise TPtr, and lengths
280 iInterfaceConfigured = ETrue;
284 TInt CBulkOnlyTransport::HwStart(TBool aDiscard)
286 __FNLOG("CBulkOnlyTransport::HwStart");
291 Controller().DriveManager().Connect(lun);
295 TInt res = StartControlInterface();
297 iCurrentState = ENone;
312 TInt CBulkOnlyTransport::HwStop()
314 __FNLOG("CBulkOnlyTransport::HwStop");
317 StopBulkOnlyEndpoint();
318 CancelControlInterface();
325 void CBulkOnlyTransport::StopBulkOnlyEndpoint()
327 __FNLOG("CBulkOnlyTransport::StopBulkOnlyEndpoint");
332 Controller().DriveManager().Disconnect(lun);
340 TInt CBulkOnlyTransport::HwSuspend()
342 __FNLOG("CBulkOnlyTransport::HwSuspend");
347 Controller().DriveManager().Disconnect(lun);
355 TInt CBulkOnlyTransport::HwResume()
357 __FNLOG("CBulkOnlyTransport::HwResume");
362 Controller().DriveManager().Connect(lun);
370 Stops the Bulk Only Transport
372 TInt CBulkOnlyTransport::Stop()
374 __FNLOG("CBulkOnlyTransport::Stop");
375 CancelControlInterface();
376 CancelDeviceStateNotifier();
378 if (iInterfaceConfigured)
381 SetupConfigurationDescriptor(ETrue);
383 iCurrentState = ENone;
384 iInterfaceConfigured = EFalse;
391 void CBulkOnlyTransport::DoCancel()
393 __FNLOG("CBulkOnlyTransport::DoCancel");
394 CancelReadWriteRequests();
398 void CBulkOnlyTransport::Activate(TInt aReason)
401 TRequestStatus* r = &iStatus;
402 User::RequestComplete(r, aReason);
406 void CBulkOnlyTransport::RunL()
408 __FNLOG("CBulkOnlyTransport::RunL");
409 if (iStatus != KErrNone)
411 __PRINT1(_L("Error %d in RunL, halt endpoints \n"), iStatus.Int());
412 SetPermError(); //halt endpoints for reset recovery
415 switch (iCurrentState)
418 __PRINT(_L("EWaitForCBW"));
423 __PRINT(_L("EWritingData"));
424 iWriteSetUp = EFalse; //the buffer was used
426 if (iDataResidue && iStallAllowed)
428 StallEndpointAndWaitForClear();
431 SendCSW(iCbwTag, iDataResidue, iCmdStatus);
436 __PRINT(_L("EReadingData"));
438 ProcessReadingDataEvent();
443 __PRINT(_L("ESendingCSW"));
448 __PRINT(_L("EPermErr"));
449 StallEndpointAndWaitForClear();
453 SetPermError(); // unexpected state
459 Decode the CBW received from the host via OutEndpoint
461 - If the header is valid, the data content is passed to the parser.
462 - Depending on the command, more data may be transmitted/received.
463 - ...or the CSW is sent (if not a data command).
466 void CBulkOnlyTransport::DecodeCBW()
468 __FNLOG("CBulkOnlyTransport::DecodeCBW");
472 if (!CheckCBW()) //check if CBW valid and meaningful
474 // CBW not valid or meaningful
475 // Specification says: "If the CBW is not valid, the device shall STALL
476 // the Bulk-In pipe. Also, the device shall either STALL the Bulk-Out pipe,
477 // or the device shall accept and discard any Bulk-Out data. The device
478 // shall maintain this state until a Reset Recovery."
479 // Here we keep bulk-in ep stalled and ignore bulk-out ep.
481 ExpireData((TAny*) (iCbwBufPtr.Ptr()));
486 aData.Set(&iCbwBufPtr[KCbwCbLengthOffset], KMaxCbwcbLength+1); //prepare data for protocol starting form Length
487 TUint8 lun = static_cast<TUint8>(iCbwBufPtr[13] & 0x0f);
489 iCbwTag = static_cast<TUint32>(iCbwBufPtr[KCbwTagOffset]) |
490 static_cast<TUint32>(iCbwBufPtr[KCbwTagOffset+1]) <<8 |
491 static_cast<TUint32>(iCbwBufPtr[KCbwTagOffset+2]) <<16|
492 static_cast<TUint32>(iCbwBufPtr[KCbwTagOffset+3]) <<24;
494 TInt i = KCbwDataTransferLengthOffset;
495 TUint hostDataLength = static_cast<TUint32>(iCbwBufPtr[i ]) |
496 static_cast<TUint32>(iCbwBufPtr[i+1]) <<8 |
497 static_cast<TUint32>(iCbwBufPtr[i+2]) <<16 |
498 static_cast<TUint32>(iCbwBufPtr[i+3]) <<24;
500 TBool dataToHost = iCbwBufPtr[KCbwFlagOffset] & 0x80;
502 __PRINT4(_L("lun =%d, hostDataLength=%d, CBWtag = 0x%x, dataToHost=%d\n"), lun, hostDataLength, iCbwTag, dataToHost);
503 //////////////////////////////////////////////
504 TBool ret = iProtocol->DecodePacket(aData, lun);
505 //////////////////////////////////////////////
506 ExpireData((TAny*) (iCbwBufPtr.Ptr()));
509 iStallAllowed = ETrue;
513 __PRINT(_L("Command Failed\n"));
514 iCmdStatus = ECommandFailed;
518 __PRINT(_L("Command Passed\n"));
519 iCmdStatus = ECommandPassed;
522 if (hostDataLength) // Host expected data transfer
524 if (dataToHost) // send data to host
526 if (!iWriteSetUp) //write buffer was not set up
528 __PRINT(_L("Write buffer was not setup\n"));
529 iDataResidue =hostDataLength;
530 __PRINT1(_L("DataResidue (write to host)=%d\n"),iDataResidue);
532 //------------------------------------
533 if (hostDataLength <= KBOTMaxBufSize)
535 __PRINT(_L("Case 4 or 8\n"));
536 SetPaddingBufPtr(hostDataLength);
537 iPaddingBufPtr.FillZ(hostDataLength);
539 ptr.Set((TUint8*)iPaddingBufPtr.Ptr(), hostDataLength);
540 WriteData(iStatus, ptr, hostDataLength, EFalse);
541 iStallAllowed = EFalse;
542 if (iReadSetUp) //read buffer WAS set up - case (8)
544 __PRINT(_L("It is Case 8\n"));
545 iCmdStatus = EPhaseError;
550 //------------------------------------
551 // Use next block instead of StallEndpointAndWaitForClear(InEndpoint);
553 SetPaddingBufPtr(hostDataLength);
554 iPaddingBufPtr.FillZ(KBOTMaxBufSize);
556 TRequestStatus status;
557 while (c<hostDataLength)
560 if (hostDataLength - c > KBOTMaxBufSize)
562 len = KBOTMaxBufSize;
566 len = hostDataLength - c;
570 ptr.Set((TUint8*)iPaddingBufPtr.Ptr(), len);
571 WriteUsb(status, ptr, len);
572 User::WaitForRequest(status);
577 if (iReadSetUp) //read buffer WAS set up - case (8)
579 __PRINT(_L("Case 8\n"));
580 SendCSW(iCbwTag, hostDataLength, EPhaseError);
581 //don't care to reset any flag - should get reset recovery
585 __PRINT(_L("Case 4\n"));
586 SendCSW(iCbwTag, hostDataLength, iCmdStatus);
589 } // if (!iWriteSetUp)
592 TUint deviceDataLength = static_cast<TUint>(iWriteBufPtr.Length());
593 iDataResidue =hostDataLength - deviceDataLength ;
594 __PRINT2(_L("Device data length = %d, DataResidue (write to host)=%d\n"), deviceDataLength, iDataResidue);
596 if (deviceDataLength < hostDataLength &&
597 hostDataLength < KBOTMaxBufSize )
599 __PRINT(_L("Case 5 (padding)\n"));
600 SetPaddingBufPtr(hostDataLength);
601 iPaddingBufPtr.Zero();
602 iPaddingBufPtr.Append(iWriteBufPtr);
603 iStallAllowed = EFalse;
604 __PRINT1(_L("iPaddingBufPtr.Length = %d\n"),iPaddingBufPtr.Length());
606 ptr.Set((TUint8*)iPaddingBufPtr.Ptr(), hostDataLength);
607 WriteData(iStatus, ptr, hostDataLength, EFalse);
611 //===================
613 if (deviceDataLength == hostDataLength) //case (6)[==]
615 __PRINT(_L("Case 6\n"));
616 WriteData(iStatus, iWriteBufPtr, deviceDataLength);
619 else if (deviceDataLength < hostDataLength) //case (5)[<]
621 __PRINT(_L("Case 5\n"));
622 WriteData(iStatus, iWriteBufPtr, deviceDataLength, ETrue); // Send ZLP
625 else // deviceDataLength > hostDataLength - case (7)
627 __PRINT(_L("Case 7\n"));
628 iCmdStatus = EPhaseError;
630 WriteData(iStatus, iWriteBufPtr, hostDataLength);
634 else //read data from host
638 iDataResidue = hostDataLength;
639 __PRINT(_L("Read buffer was not setup\n"));
640 // Use next block instead of StallEndpointAndWaitForClear(OutEndpoint);
641 DiscardData(hostDataLength);
643 if (iWriteSetUp) //case (10)
645 __PRINT(_L("case 10\n"));
646 SendCSW(iCbwTag, hostDataLength, EPhaseError);
650 __PRINT(_L("Case 9\n"));
651 SendCSW(iCbwTag, hostDataLength, iCmdStatus);
657 TUint deviceDataLength = iBufSize;
658 iDataResidue = hostDataLength; // calculate residue later
660 __PRINT2(_L("deviceDataLength = iBufSize = %d, DataResidue = HDL for now (read from host) =%d\n"),deviceDataLength,iDataResidue);
662 if (deviceDataLength <= hostDataLength) // case (11) and (12)
664 __PRINT(_L("Case 11 or 12\n"));
665 ReadData(deviceDataLength);
668 if (deviceDataLength > hostDataLength) // case (13)
670 __PRINT(_L("Case 13\n"));
672 * Comment following line in order to pass compliant test.
673 * As spec said in case 13:"The device may receive data up to a
674 * total of dCBWDataTransferLength."
675 * Here we choose to ignore incoming data.
677 //StallEndpointAndWaitForClear(OutEndpoint); //Stall Out endpoint
680 WriteToClient(hostDataLength);
683 SendCSW(iCbwTag, hostDataLength, EPhaseError);
688 else // Host expected no data transfer
690 __PRINT(_L("No data transfer expected\n"));
692 if (iWriteSetUp || iReadSetUp) // case (2) and (3)
694 __PRINT(_L("Case 2 or 3\n"));
695 SendCSW(iCbwTag, 0, EPhaseError);
699 __PRINT(_L("Case 1\n"));
700 SendCSW(iCbwTag, 0, iCmdStatus); //case (1)
707 Check if CBW Valid and Meaningful.
709 @return ETrue if CBW is Valid and Meaningful, EFalse otherwise
711 TBool CBulkOnlyTransport::CheckCBW()
713 __FNLOG("CBulkOnlyTransport::CheckCBW");
720 if ((TUint) (iCbwBufPtr.Length()) != KCbwLength)
722 __PRINT2(_L("Bad length: %d != KCbwLength"), iCbwBufPtr.Length(), KCbwLength);
727 TInt i = KCbwSignatureOffset;
728 if (iCbwBufPtr[i ] != 0x55 || // CBW Singature from USB Bulk-Only Transport spec
729 iCbwBufPtr[i+1] != 0x53 ||
730 iCbwBufPtr[i+2] != 0x42 ||
731 iCbwBufPtr[i+3] != 0x43)
733 __PRINT(_L("Bad signature"));
734 __PRINT4(_L(" 0x%x, 0x%x, 0x%x, 0x%x \n"), iCbwBufPtr[i], iCbwBufPtr[i+1], iCbwBufPtr[i+2],iCbwBufPtr[i+3])
742 // Check reserved bits ( must be zero )
743 if ((iCbwBufPtr[KCbwLunOffset] & 0xF0) || (iCbwBufPtr[KCbwCbLengthOffset] & 0xE0))
745 __PRINT(_L("Reserved bits not zero\n"));
749 // check command block length
750 TInt cbwcbLength = iCbwBufPtr[KCbwCbLengthOffset] & 0x1F;
751 if (cbwcbLength >KMaxCbwcbLength)
753 __PRINT(_L("Incorrect block length\n"));
758 TInt8 lun = static_cast<TUint8>(iCbwBufPtr[KCbwLunOffset] & 0x0f);
761 __PRINT1(_L("bad lun: %d"), lun);
770 Initiate stalling of bulk IN endpoint.
771 Used when protocol wants to force host to initiate a reset recovery.
773 void CBulkOnlyTransport::SetPermError()
775 __FNLOG("CBulkOnlyTransport::SetPermError");
776 iCurrentState = EPermErr;
782 Send data provided by protocol to the host
784 @param aLength amount of data (in bytes) to be send to host
786 void CBulkOnlyTransport::WriteData(TRequestStatus& aStatus, TPtrC8& aDes, TUint aLength, TBool aZlpRequired)
788 __FNLOG("CBulkOnlyTransport::WriteData");
792 __PRINT(_L("Still active\n"));
793 __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive));
796 WriteUsb(aStatus, aDes, aLength, aZlpRequired);
797 iCurrentState = EWritingData;
803 Send Command Status Wrapper to the host
805 @param aTag Echo of Command Block Tag sent by the host.
806 @param aDataResidue the difference between the amount of data expected by the
807 host, and the actual amount of data processed by the device.
808 @param aStatus indicates the success or failure of the command.
810 void CBulkOnlyTransport::SendCSW(TUint aTag, TUint aDataResidue, TCswStatus aStatus)
812 __FNLOG("CBulkOnlyTransport::SendCSW");
813 __PRINT2(_L("DataResidue = %d, Status = %d \n"), aDataResidue, aStatus);
817 __PRINT(_L("Still active\n"));
818 __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive));
822 SetCswBufPtr(KCswLength);
823 TInt i = KCswSingnatureOffset;
824 iCswBufPtr[i ] = 0x55; // CSW Singature from USB Bulk-Only Transport spec
825 iCswBufPtr[i+1] = 0x53;
826 iCswBufPtr[i+2] = 0x42;
827 iCswBufPtr[i+3] = 0x53;
831 iCswBufPtr[i ] = static_cast<TUint8>((aTag & 0x000000FF));
832 iCswBufPtr[i+1] = static_cast<TUint8>((aTag & 0x0000FF00) >> 8);
833 iCswBufPtr[i+2] = static_cast<TUint8>((aTag & 0x00FF0000) >> 16);
834 iCswBufPtr[i+3] = static_cast<TUint8>((aTag & 0xFF000000) >> 24);
836 i = KCswDataResidueOffset;
837 iCswBufPtr[i ] = static_cast<TUint8>((aDataResidue & 0x000000FF));
838 iCswBufPtr[i+1] = static_cast<TUint8>((aDataResidue & 0x0000FF00) >> 8);
839 iCswBufPtr[i+2] = static_cast<TUint8>((aDataResidue & 0x00FF0000) >> 16);
840 iCswBufPtr[i+3] = static_cast<TUint8>((aDataResidue & 0xFF000000) >> 24);
842 iCswBufPtr[KCswStatusOffset] = static_cast<TUint8>(aStatus);
845 ptr.Set((const TUint8*)iCswBufPtr.Ptr(), KCswLength);
847 WriteUsb(iStatus, ptr, KCswLength);
849 iCurrentState = ESendingCSW;
856 Associates the transport with the protocol. Called during initialization of the controller.
858 @param aProtocol reference to the protocol
860 void CBulkOnlyTransport::RegisterProtocol(MProtocolBase& aProtocol)
862 __FNLOG("CBulkOnlyTransport::RegisterProtocol");
863 iProtocol = &aProtocol;
868 Used by CControlInterface
870 @return reference to the controller which instantiate the CBulkOnlyTransport
872 CUsbMassStorageController& CBulkOnlyTransport::Controller()
879 @return the number of logical units supported by the device.
880 Logical Unit Numbers on the device shall be numbered contiguously starting from LUN
881 0 to a maximum LUN of 15 (Fh).
883 TInt CBulkOnlyTransport::MaxLun()
889 void CBulkOnlyTransport::GetCommandBufPtr(TPtr8& aDes, TUint aLength) // Set pointer to buffer of specified aLength for command
891 aDes.Set(SetCommandBufPtr(aLength));
894 void CBulkOnlyTransport::GetReadDataBufPtr(TPtr8& aDes) // Set pointer to buffer into which data is to be read from drive (Read10)
896 aDes.Set(SetDataBufPtr());
900 void CBulkOnlyTransport::GetWriteDataBufPtr(TPtrC8& aDes) // Set pointer to buffer from which data is to be written to drive (Write10)
902 aDes.Set(iReadBufPtr);
905 #ifdef MSDC_MULTITHREADED
906 void CBulkOnlyTransport::ProcessReadData(TAny* aAddress)
908 ExpireData(aAddress);