sl@0
|
1 |
// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// e32\drivers\usbcsc\d_usbcsc.cpp
|
sl@0
|
15 |
// LDD for USB Device driver stack, using shared chunks:
|
sl@0
|
16 |
// The channel object.
|
sl@0
|
17 |
//
|
sl@0
|
18 |
//
|
sl@0
|
19 |
|
sl@0
|
20 |
/**
|
sl@0
|
21 |
@file d_usbcsc.cpp
|
sl@0
|
22 |
@internalTechnology
|
sl@0
|
23 |
*/
|
sl@0
|
24 |
|
sl@0
|
25 |
#include <drivers/usbcsc.h>
|
sl@0
|
26 |
#include "platform.h"
|
sl@0
|
27 |
|
sl@0
|
28 |
/*****************************************************************************\
|
sl@0
|
29 |
* DUsbcScLogDevice *
|
sl@0
|
30 |
* *
|
sl@0
|
31 |
* Inherits from DLogicalDevice, the USB Shared Chunk LDD factory class *
|
sl@0
|
32 |
* *
|
sl@0
|
33 |
\*****************************************************************************/
|
sl@0
|
34 |
|
sl@0
|
35 |
_LIT(KUsbScLddName, "Usbcsc");
|
sl@0
|
36 |
|
sl@0
|
37 |
static const TInt KUsbRequestCallbackPriority = 2;
|
sl@0
|
38 |
|
sl@0
|
39 |
/** Real entry point from the Kernel: return a new driver.
|
sl@0
|
40 |
*/
|
sl@0
|
41 |
DECLARE_STANDARD_LDD()
|
sl@0
|
42 |
{
|
sl@0
|
43 |
return new DUsbcScLogDevice;
|
sl@0
|
44 |
}
|
sl@0
|
45 |
|
sl@0
|
46 |
/** Create a channel on the device.
|
sl@0
|
47 |
|
sl@0
|
48 |
@internalComponent
|
sl@0
|
49 |
*/
|
sl@0
|
50 |
TInt DUsbcScLogDevice::Create(DLogicalChannelBase*& aChannel)
|
sl@0
|
51 |
{
|
sl@0
|
52 |
aChannel = new DLddUsbcScChannel;
|
sl@0
|
53 |
return aChannel ? KErrNone : KErrNoMemory;
|
sl@0
|
54 |
}
|
sl@0
|
55 |
|
sl@0
|
56 |
|
sl@0
|
57 |
DUsbcScLogDevice::DUsbcScLogDevice()
|
sl@0
|
58 |
{
|
sl@0
|
59 |
iParseMask = KDeviceAllowUnit;
|
sl@0
|
60 |
iUnitsMask = 0xffffffff; // Leave units decision to the Controller
|
sl@0
|
61 |
iVersion = TVersion(KUsbcScMajorVersion, KUsbcScMinorVersion, KUsbcScBuildVersion);
|
sl@0
|
62 |
}
|
sl@0
|
63 |
|
sl@0
|
64 |
|
sl@0
|
65 |
TInt DUsbcScLogDevice::Install()
|
sl@0
|
66 |
{
|
sl@0
|
67 |
// Only proceed if we have the Controller underneath us
|
sl@0
|
68 |
if (!DUsbClientController::UsbcControllerPointer())
|
sl@0
|
69 |
{
|
sl@0
|
70 |
__KTRACE_OPT(KPANIC, Kern::Printf("LDD Install: USB Controller Not Present"));
|
sl@0
|
71 |
return KErrGeneral;
|
sl@0
|
72 |
}
|
sl@0
|
73 |
return SetName(&KUsbScLddName);
|
sl@0
|
74 |
}
|
sl@0
|
75 |
|
sl@0
|
76 |
|
sl@0
|
77 |
//
|
sl@0
|
78 |
// Return the USB controller capabilities.
|
sl@0
|
79 |
//
|
sl@0
|
80 |
void DUsbcScLogDevice::GetCaps(TDes8& aDes) const
|
sl@0
|
81 |
{
|
sl@0
|
82 |
TPckgBuf<TCapsDevUsbc> b;
|
sl@0
|
83 |
b().version = iVersion;
|
sl@0
|
84 |
Kern::InfoCopy(aDes, b);
|
sl@0
|
85 |
}
|
sl@0
|
86 |
|
sl@0
|
87 |
// End DUsbcScLogDevice
|
sl@0
|
88 |
|
sl@0
|
89 |
/*****************************************************************************\
|
sl@0
|
90 |
* TUsbcScChunkInfo *
|
sl@0
|
91 |
* *
|
sl@0
|
92 |
* Where Chunk information is stored for the channel, and preseved for the *
|
sl@0
|
93 |
* life of the chunk. *
|
sl@0
|
94 |
* *
|
sl@0
|
95 |
\*****************************************************************************/
|
sl@0
|
96 |
|
sl@0
|
97 |
void DfcChunkCleanup(TAny*);
|
sl@0
|
98 |
|
sl@0
|
99 |
TUsbcScChunkInfo::TUsbcScChunkInfo(DLogicalDevice* aLdd)
|
sl@0
|
100 |
: iChunk(NULL),
|
sl@0
|
101 |
iCleanup((TDfcFn)&DfcChunkCleanup,this,Kern::SvMsgQue(),0),
|
sl@0
|
102 |
iChunkMem(NULL),
|
sl@0
|
103 |
iLdd(aLdd)
|
sl@0
|
104 |
{
|
sl@0
|
105 |
iPageNtz = (TInt8)__e32_find_ls1_32(Kern::RoundToPageSize(1));
|
sl@0
|
106 |
}
|
sl@0
|
107 |
|
sl@0
|
108 |
TInt TUsbcScChunkInfo::CreateChunk(TInt aTotalSize)
|
sl@0
|
109 |
{
|
sl@0
|
110 |
// First, reserve an TUint of memory for each of pages needed to hold aTotalSize of memory.
|
sl@0
|
111 |
// This will form the chunk map, so that we can look up the memory geometry.
|
sl@0
|
112 |
iAllocatedSize = (aTotalSize>>iPageNtz)*sizeof(TUint);
|
sl@0
|
113 |
iPhysicalMap = (TUint*) Kern::AllocZ(iAllocatedSize);
|
sl@0
|
114 |
TInt r;
|
sl@0
|
115 |
if (iPhysicalMap==NULL)
|
sl@0
|
116 |
r = KErrNoMemory;
|
sl@0
|
117 |
else
|
sl@0
|
118 |
{
|
sl@0
|
119 |
TChunkCreateInfo chunkInfo;
|
sl@0
|
120 |
chunkInfo.iType = TChunkCreateInfo::ESharedKernelMultiple;
|
sl@0
|
121 |
chunkInfo.iMaxSize = aTotalSize;
|
sl@0
|
122 |
chunkInfo.iMapAttr = EMapAttrCachedMax;
|
sl@0
|
123 |
chunkInfo.iOwnsMemory = EFalse;
|
sl@0
|
124 |
chunkInfo.iDestroyedDfc = &iCleanup;
|
sl@0
|
125 |
|
sl@0
|
126 |
TLinAddr chunkMem;
|
sl@0
|
127 |
r = Kern::ChunkCreate(chunkInfo, iChunk, chunkMem, iChunkMapAttr);
|
sl@0
|
128 |
iChunkMem = (TInt8*) chunkMem;
|
sl@0
|
129 |
if (r==KErrNone)
|
sl@0
|
130 |
iLdd->Open();
|
sl@0
|
131 |
}
|
sl@0
|
132 |
|
sl@0
|
133 |
return r;
|
sl@0
|
134 |
}
|
sl@0
|
135 |
|
sl@0
|
136 |
|
sl@0
|
137 |
// This method requests closing the chunk.
|
sl@0
|
138 |
// Note that nothing may happen immediately, as something else may have the chunk open.
|
sl@0
|
139 |
void TUsbcScChunkInfo::Close()
|
sl@0
|
140 |
{
|
sl@0
|
141 |
Kern::ChunkClose(iChunk);
|
sl@0
|
142 |
}
|
sl@0
|
143 |
|
sl@0
|
144 |
|
sl@0
|
145 |
TInt TUsbcScChunkInfo::ChunkAlloc(TInt aOffset, TInt aSize)
|
sl@0
|
146 |
{
|
sl@0
|
147 |
TUint pageMask = (~0)<<iPageNtz;
|
sl@0
|
148 |
TUint rleMask = ~pageMask;
|
sl@0
|
149 |
TUint pageSize = rleMask+1;
|
sl@0
|
150 |
TInt r;
|
sl@0
|
151 |
TLinAddr physAddr;
|
sl@0
|
152 |
|
sl@0
|
153 |
__KTRACE_OPT(KUSB, Kern::Printf("::chunkalloc AllocPhysicalRam aSize %d", aSize));
|
sl@0
|
154 |
|
sl@0
|
155 |
r = Epoc::AllocPhysicalRam(aSize, physAddr);
|
sl@0
|
156 |
__KTRACE_OPT(KUSB, if (r!=KErrNone) Kern::Printf("::chunkalloc AllocPhysicalRam r=%d (Error!)", r));
|
sl@0
|
157 |
if (r==KErrNone)
|
sl@0
|
158 |
{
|
sl@0
|
159 |
__KTRACE_OPT(KUSB, Kern::Printf("::chunkalloc ChunkCommitPhysical iChunk 0x%x size(%d), aOffset 0x%x, aSize 0x%x phsAddr 0x%x",
|
sl@0
|
160 |
iChunk, sizeof(DChunk), aOffset, aSize,physAddr ));
|
sl@0
|
161 |
|
sl@0
|
162 |
r = Kern::ChunkCommitPhysical(iChunk, aOffset, aSize, physAddr);
|
sl@0
|
163 |
__KTRACE_OPT(KUSB, if (r!=KErrNone) Kern::Printf("::chunkalloc ChunkCommitPhysical r=%d (Error!)", r));
|
sl@0
|
164 |
|
sl@0
|
165 |
if (r!=KErrNone)
|
sl@0
|
166 |
Epoc::FreePhysicalRam(physAddr, aSize);
|
sl@0
|
167 |
else
|
sl@0
|
168 |
{ // record physical address and length in physical map
|
sl@0
|
169 |
TInt rle;
|
sl@0
|
170 |
TInt i=0;
|
sl@0
|
171 |
for (rle=(aSize>>iPageNtz); rle>0; rle--, i++,physAddr+=pageSize)
|
sl@0
|
172 |
{
|
sl@0
|
173 |
__KTRACE_OPT(KUSB, Kern::Printf("::phys offset 0x%x = 0x%x",
|
sl@0
|
174 |
(aOffset>>iPageNtz)+i, (physAddr & pageMask) | ((rle>(TInt)rleMask)?(TInt)rleMask:rle)));
|
sl@0
|
175 |
iPhysicalMap[(aOffset>>iPageNtz)+i] = (physAddr & pageMask) | ((rle>(TInt)rleMask)?(TInt)rleMask:rle);
|
sl@0
|
176 |
}
|
sl@0
|
177 |
}
|
sl@0
|
178 |
}
|
sl@0
|
179 |
else if (r==KErrNoMemory)
|
sl@0
|
180 |
r = -KErrNoMemory; // Semi-expected error.
|
sl@0
|
181 |
return r;
|
sl@0
|
182 |
}
|
sl@0
|
183 |
|
sl@0
|
184 |
/**
|
sl@0
|
185 |
This method retrieves the physical address of a given offset into the Chunk, and returns
|
sl@0
|
186 |
the length of contiguous physical memory from this point.
|
sl@0
|
187 |
|
sl@0
|
188 |
@param aOffset the offset from the start of the chunk, to be queried.
|
sl@0
|
189 |
@param aPhysical a pointer to a TPhysAddr, to be filled with the physical
|
sl@0
|
190 |
address of the memory at the given offset.
|
sl@0
|
191 |
|
sl@0
|
192 |
@returns the length of contiguous physical memory from the given offset.
|
sl@0
|
193 |
*/
|
sl@0
|
194 |
|
sl@0
|
195 |
TInt TUsbcScChunkInfo::GetPhysical(TInt aOffset, TPhysAddr* aPhysical)
|
sl@0
|
196 |
{
|
sl@0
|
197 |
// Use masks, to retrieve the two components from the physical map, we created of the memory.
|
sl@0
|
198 |
TUint pageMask = (~0)<<iPageNtz;
|
sl@0
|
199 |
TUint val = iPhysicalMap[aOffset>>iPageNtz];
|
sl@0
|
200 |
*aPhysical=(val & pageMask)+(aOffset & ~pageMask);
|
sl@0
|
201 |
return ((val & ~pageMask)<<iPageNtz) - (aOffset & ~pageMask);
|
sl@0
|
202 |
}
|
sl@0
|
203 |
|
sl@0
|
204 |
|
sl@0
|
205 |
// DFC calls this fuction, which invokes the cleanup method.
|
sl@0
|
206 |
|
sl@0
|
207 |
void DfcChunkCleanup(TAny* aChunkInfo)
|
sl@0
|
208 |
{
|
sl@0
|
209 |
((TUsbcScChunkInfo*) aChunkInfo)->ChunkCleanup();
|
sl@0
|
210 |
}
|
sl@0
|
211 |
|
sl@0
|
212 |
|
sl@0
|
213 |
void TUsbcScChunkInfo::ChunkCleanup()
|
sl@0
|
214 |
{
|
sl@0
|
215 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScChunkInfo::ChunkCleanup()"));
|
sl@0
|
216 |
TUint physAddr;
|
sl@0
|
217 |
TInt length;
|
sl@0
|
218 |
TInt offset = 0;
|
sl@0
|
219 |
|
sl@0
|
220 |
// The part of the field used for the physical page address.
|
sl@0
|
221 |
TUint pageMask = (~0)<<iPageNtz;
|
sl@0
|
222 |
|
sl@0
|
223 |
// The part of the field used for the run length encoding, of the contiguous pages.
|
sl@0
|
224 |
TUint rleMask = ~pageMask;
|
sl@0
|
225 |
TInt records=(iAllocatedSize>>2);
|
sl@0
|
226 |
|
sl@0
|
227 |
while (offset < records)
|
sl@0
|
228 |
{
|
sl@0
|
229 |
physAddr = iPhysicalMap[offset] & pageMask;
|
sl@0
|
230 |
length = iPhysicalMap[offset] & rleMask;
|
sl@0
|
231 |
|
sl@0
|
232 |
if (physAddr>0)
|
sl@0
|
233 |
Epoc::FreePhysicalRam(physAddr, length);
|
sl@0
|
234 |
|
sl@0
|
235 |
offset += (length>0)?length:1;
|
sl@0
|
236 |
}
|
sl@0
|
237 |
Kern::Free(iPhysicalMap);
|
sl@0
|
238 |
|
sl@0
|
239 |
DLogicalDevice* ldd = iLdd;
|
sl@0
|
240 |
delete this;
|
sl@0
|
241 |
ldd->Close(NULL);
|
sl@0
|
242 |
}
|
sl@0
|
243 |
|
sl@0
|
244 |
TInt TUsbcScChunkInfo::New(TUsbcScChunkInfo*& aChunk, TInt aSize, DLogicalDevice* aLdd)
|
sl@0
|
245 |
{
|
sl@0
|
246 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScChunkInfo::New totalSize %d", aSize));
|
sl@0
|
247 |
|
sl@0
|
248 |
aChunk = new TUsbcScChunkInfo(aLdd);
|
sl@0
|
249 |
if (aChunk==NULL)
|
sl@0
|
250 |
{
|
sl@0
|
251 |
return KErrNoMemory;
|
sl@0
|
252 |
}
|
sl@0
|
253 |
|
sl@0
|
254 |
TInt r = aChunk->CreateChunk(aSize);
|
sl@0
|
255 |
if (r!=KErrNone)
|
sl@0
|
256 |
{
|
sl@0
|
257 |
delete aChunk;
|
sl@0
|
258 |
aChunk=NULL;
|
sl@0
|
259 |
return r;
|
sl@0
|
260 |
}
|
sl@0
|
261 |
|
sl@0
|
262 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScChunkInfo::New Created at 0x%x", aChunk->iChunkMem ));
|
sl@0
|
263 |
return KErrNone;
|
sl@0
|
264 |
}
|
sl@0
|
265 |
|
sl@0
|
266 |
// End TUsbcScChunkInfo
|
sl@0
|
267 |
|
sl@0
|
268 |
/*****************************************************************************\
|
sl@0
|
269 |
* TUsbcScBuffer *
|
sl@0
|
270 |
* *
|
sl@0
|
271 |
* Represents a buffer, within a chunk. Each buffers can be used by *
|
sl@0
|
272 |
* differt endpoint on differnt alt settings *
|
sl@0
|
273 |
* *
|
sl@0
|
274 |
\*****************************************************************************/
|
sl@0
|
275 |
|
sl@0
|
276 |
|
sl@0
|
277 |
TInt TUsbcScBuffer::Construct(TInt aDirection, DLddUsbcScChannel* aLdd, TInt aBufferOffset, TInt aBufferEndOffset, TInt aMinReadSize, TInt aMaxPacketSize, TInt aMaxReadSize)
|
sl@0
|
278 |
{
|
sl@0
|
279 |
TInt r;
|
sl@0
|
280 |
#ifdef _DEBUG
|
sl@0
|
281 |
iSequence = aBufferOffset; // Initialized at this, so that each buffer starts with a diffrent sequence number
|
sl@0
|
282 |
#endif
|
sl@0
|
283 |
iMinReadSize = aMinReadSize;
|
sl@0
|
284 |
TInt size = (aBufferEndOffset - aBufferOffset);
|
sl@0
|
285 |
TInt pageSize = Kern::RoundToPageSize(1);
|
sl@0
|
286 |
if (aMaxReadSize > 0)
|
sl@0
|
287 |
iMaxReadSize = aMaxReadSize;
|
sl@0
|
288 |
else
|
sl@0
|
289 |
iMaxReadSize = pageSize + ((size/3) & ~(pageSize -1));
|
sl@0
|
290 |
iLdd = aLdd;
|
sl@0
|
291 |
iDirection = aDirection;
|
sl@0
|
292 |
iMode=0;
|
sl@0
|
293 |
iChunkInfo = aLdd->iChunkInfo;
|
sl@0
|
294 |
iChunkAddr = (TLinAddr) (aLdd->iChunkInfo->iChunkMem); //aChunkAddr;
|
sl@0
|
295 |
|
sl@0
|
296 |
TInt headerSize = sizeof(TUsbcScTransferHeader)-4; // TransferHeader includes 4 bytes of data.
|
sl@0
|
297 |
|
sl@0
|
298 |
|
sl@0
|
299 |
TUint maxAlignment; // Note: This is a mask for max Alignment,
|
sl@0
|
300 |
|
sl@0
|
301 |
if (aMaxPacketSize)
|
sl@0
|
302 |
{ // EP0 packets are not DMAed, and so dont need ialignment.
|
sl@0
|
303 |
iAlignMask = ~3;
|
sl@0
|
304 |
maxAlignment = 3;
|
sl@0
|
305 |
}
|
sl@0
|
306 |
else
|
sl@0
|
307 |
maxAlignment = 1023; // We don't know what the alignment requirement will be until enumeration, so assume worse case.
|
sl@0
|
308 |
|
sl@0
|
309 |
iFirstPacket = aBufferOffset + sizeof(SUsbcScBufferHeader) + headerSize;
|
sl@0
|
310 |
iFirstPacket = (iFirstPacket + maxAlignment) & ~maxAlignment;
|
sl@0
|
311 |
|
sl@0
|
312 |
iBufferStart = (SUsbcScBufferHeader *) (iChunkAddr+aBufferOffset);
|
sl@0
|
313 |
iBufferEnd = aBufferEndOffset;
|
sl@0
|
314 |
|
sl@0
|
315 |
if ((iDirection&1)==KUsbcScOut)
|
sl@0
|
316 |
iHead = iFirstPacket-headerSize;//aBufferOffset + sizeof(SUsbcScBufferHeader);
|
sl@0
|
317 |
else
|
sl@0
|
318 |
iSent = 0;
|
sl@0
|
319 |
|
sl@0
|
320 |
iStalled=0;
|
sl@0
|
321 |
iMaxPacketSize=0;
|
sl@0
|
322 |
|
sl@0
|
323 |
r = iStatusList.Construct((aDirection==KUsbcScIn)?KUsbcScInRequests:KUsbcScOutRequests, iLdd->iClient);
|
sl@0
|
324 |
if (!r)
|
sl@0
|
325 |
{
|
sl@0
|
326 |
iMaxPacketSize = aMaxPacketSize; // Indicates configured if ep0, otherwise not.
|
sl@0
|
327 |
}
|
sl@0
|
328 |
return r;
|
sl@0
|
329 |
}
|
sl@0
|
330 |
|
sl@0
|
331 |
|
sl@0
|
332 |
void TUsbcScBuffer::CreateChunkBufferHeader()
|
sl@0
|
333 |
{
|
sl@0
|
334 |
if ((iDirection&1)==KUsbcScOut)
|
sl@0
|
335 |
{
|
sl@0
|
336 |
iBufferStart->iHead= iHead;
|
sl@0
|
337 |
iBufferStart->iTail= iHead; // Initially no data!
|
sl@0
|
338 |
iBufferStart->iBilTail=iHead;
|
sl@0
|
339 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: iHead 0x%x bufferHeader 0x%x", iHead,iBufferStart ));
|
sl@0
|
340 |
|
sl@0
|
341 |
// Dont need to round here, as we will round it up on endpoint change. (configuration)
|
sl@0
|
342 |
}
|
sl@0
|
343 |
}
|
sl@0
|
344 |
|
sl@0
|
345 |
/*
|
sl@0
|
346 |
TUsbcScBuffer::StartEndpoint
|
sl@0
|
347 |
|
sl@0
|
348 |
This method sets the nessesary paramenters to the buffer, for use for a particular endpoint.
|
sl@0
|
349 |
|
sl@0
|
350 |
*/
|
sl@0
|
351 |
void TUsbcScBuffer::StartEndpoint(TUsbcRequestCallback* aRequestInfo, TUint aFlags)
|
sl@0
|
352 |
{
|
sl@0
|
353 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartEndpoint (0x%x) : ep %d(%d)",this,aRequestInfo->iEndpointNum, aRequestInfo->iRealEpNum));
|
sl@0
|
354 |
|
sl@0
|
355 |
iCallback=aRequestInfo;
|
sl@0
|
356 |
iMaxPacketSize = iLdd->iController->EndpointPacketSize(iLdd, aRequestInfo->iRealEpNum);
|
sl@0
|
357 |
iAlignMask = ~(((iMaxPacketSize+1) & 0xFFFFFFF8)-1);
|
sl@0
|
358 |
iMode = aFlags;
|
sl@0
|
359 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartEndpoint : max Packets %d, mask 0x%x flags 0x%x", iMaxPacketSize, iAlignMask, iMode));
|
sl@0
|
360 |
if ((iDirection&1)==KUsbcScOut)
|
sl@0
|
361 |
{
|
sl@0
|
362 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::UsbcScOut\n"));
|
sl@0
|
363 |
// Add dummy packet (doesnt have to be aligned, which avoids what if it changes issue)
|
sl@0
|
364 |
// And Start next read.
|
sl@0
|
365 |
iNeedsPacket=KEpIsStarting;
|
sl@0
|
366 |
}
|
sl@0
|
367 |
}
|
sl@0
|
368 |
|
sl@0
|
369 |
|
sl@0
|
370 |
|
sl@0
|
371 |
void TUsbcScBuffer::Destroy()
|
sl@0
|
372 |
{
|
sl@0
|
373 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::Destroy()"));
|
sl@0
|
374 |
Cancel(KErrCancel);
|
sl@0
|
375 |
if (iLdd->iController && ((iDirection&1)==KUsbcScOut))
|
sl@0
|
376 |
{ // Me must cancel reads to LDD to, an there will be no list for the callbacks to look into.
|
sl@0
|
377 |
iLdd->iController->CancelReadBuffer(iLdd, iCallback->iRealEpNum);
|
sl@0
|
378 |
}
|
sl@0
|
379 |
iStatusList.Destroy();
|
sl@0
|
380 |
}
|
sl@0
|
381 |
|
sl@0
|
382 |
|
sl@0
|
383 |
|
sl@0
|
384 |
TInt TUsbcScBuffer::StartDataRead()
|
sl@0
|
385 |
{
|
sl@0
|
386 |
if (!iMaxPacketSize)
|
sl@0
|
387 |
{
|
sl@0
|
388 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartDataRead() - Not Configured"));
|
sl@0
|
389 |
return KErrNone;
|
sl@0
|
390 |
}
|
sl@0
|
391 |
if (iStatusList.iState!=ENotRunning)
|
sl@0
|
392 |
{
|
sl@0
|
393 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartDataRead() - Already Stated! (%d)",iStatusList.iState));
|
sl@0
|
394 |
return KErrNone;
|
sl@0
|
395 |
}
|
sl@0
|
396 |
|
sl@0
|
397 |
TInt maxLength;
|
sl@0
|
398 |
TInt freeSpace;
|
sl@0
|
399 |
TPhysAddr physAddr;
|
sl@0
|
400 |
|
sl@0
|
401 |
// get next request
|
sl@0
|
402 |
TUsbcScStatusElement* nextJob = iStatusList.Next();
|
sl@0
|
403 |
if (nextJob == NULL)
|
sl@0
|
404 |
{
|
sl@0
|
405 |
__KTRACE_OPT(KUSB, Kern::Printf("No more jobs"));
|
sl@0
|
406 |
if (iMode && KUsbScCoupledRead)
|
sl@0
|
407 |
return KErrEof;
|
sl@0
|
408 |
iStatusList.iState=EReadingAhead;
|
sl@0
|
409 |
}
|
sl@0
|
410 |
else
|
sl@0
|
411 |
iStatusList.iState=EInProgress;
|
sl@0
|
412 |
|
sl@0
|
413 |
TInt tail = iBufferStart->iTail;
|
sl@0
|
414 |
TInt headerSize = sizeof(TUsbcScTransferHeader)-4; // TransferHeader includes 4 bytes of data.
|
sl@0
|
415 |
maxLength = iChunkInfo->GetPhysical(iHead + headerSize, &physAddr); //returns all the bytes available after iHead + headerSize)
|
sl@0
|
416 |
|
sl@0
|
417 |
__ASSERT_DEBUG(maxLength>0,Kern::Fault("TUsbcScBuffer::StartDataRead(", __LINE__));
|
sl@0
|
418 |
|
sl@0
|
419 |
|
sl@0
|
420 |
if (tail>iHead) // # # # H _ _ _ T # # # #
|
sl@0
|
421 |
{
|
sl@0
|
422 |
__KTRACE_OPT(KUSB,Kern::Printf("TUsbcScBuffer::StartDataRead() - tail 0x%x>head 0x%x, maxlength 0x%x", tail, iHead, maxLength));
|
sl@0
|
423 |
|
sl@0
|
424 |
freeSpace = (tail & iAlignMask) - (iHead +headerSize + (~iAlignMask+1) ); // Cant read right up to last buffer, or head/tail will cross.
|
sl@0
|
425 |
|
sl@0
|
426 |
if (freeSpace<iMinReadSize)
|
sl@0
|
427 |
{
|
sl@0
|
428 |
iStatusList.iState=ENotRunning;
|
sl@0
|
429 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartDataRead() - Stall!!"));
|
sl@0
|
430 |
return KErrOverflow; // Read STALL !! !! !!
|
sl@0
|
431 |
}
|
sl@0
|
432 |
|
sl@0
|
433 |
if (freeSpace<maxLength)
|
sl@0
|
434 |
maxLength = freeSpace;
|
sl@0
|
435 |
}
|
sl@0
|
436 |
if (maxLength> iMaxReadSize)
|
sl@0
|
437 |
maxLength = iMaxReadSize;
|
sl@0
|
438 |
// else tail<iHead (or empty) _ _ _ T # # # H _ _ _ _
|
sl@0
|
439 |
// We would not have set iHead here if too small. So must be ok.
|
sl@0
|
440 |
|
sl@0
|
441 |
__ASSERT_DEBUG(maxLength>=iMinReadSize,Kern::Fault("TUsbcScBuffer::StartDataRead(", __LINE__));
|
sl@0
|
442 |
|
sl@0
|
443 |
TUint8* data = ((TUsbcScTransferHeader *) (iHead + iChunkAddr))->iData.b;
|
sl@0
|
444 |
// set up callback stucture
|
sl@0
|
445 |
|
sl@0
|
446 |
iCallback->SetRxBufferInfo(data, physAddr, iIndexArray, iSizeArray,maxLength);
|
sl@0
|
447 |
TInt r;
|
sl@0
|
448 |
// Go!!
|
sl@0
|
449 |
r = iLdd->iController->SetupReadBuffer(*iCallback);
|
sl@0
|
450 |
if (r!=KErrNone)
|
sl@0
|
451 |
{
|
sl@0
|
452 |
__KTRACE_OPT(KUSB,Kern::Printf("SetupReadBuffer Error: %d, RT %d",r, iStatusList.iState));
|
sl@0
|
453 |
iStatusList.Complete(r);
|
sl@0
|
454 |
}
|
sl@0
|
455 |
// After this, TUsbcScEndpoint::RequestCallback is called in a DFC.
|
sl@0
|
456 |
// This in turn calls either TUsbcScBuffer::CompleteRead.
|
sl@0
|
457 |
return KErrNone;
|
sl@0
|
458 |
}
|
sl@0
|
459 |
|
sl@0
|
460 |
|
sl@0
|
461 |
void TUsbcScBuffer::CompleteRead(TBool aStartNextRead)
|
sl@0
|
462 |
{
|
sl@0
|
463 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::CompleteRead buff=%x",this));
|
sl@0
|
464 |
|
sl@0
|
465 |
// The first packet always contains the total #of bytes
|
sl@0
|
466 |
const TInt byteCount = iCallback->iPacketSize[0];
|
sl@0
|
467 |
const TInt packetCount = iCallback->iRxPackets;
|
sl@0
|
468 |
iCallback->iRxPackets=0;
|
sl@0
|
469 |
TUint flags = 0;
|
sl@0
|
470 |
|
sl@0
|
471 |
if (iCallback->iPacketSize[packetCount - 1] < (TUint) iMaxPacketSize)
|
sl@0
|
472 |
flags = KUsbcScShortPacket;
|
sl@0
|
473 |
|
sl@0
|
474 |
UpdateBufferList(byteCount, flags, aStartNextRead);
|
sl@0
|
475 |
}
|
sl@0
|
476 |
|
sl@0
|
477 |
|
sl@0
|
478 |
// This method "submits" the current transfer, and starts off the next read.
|
sl@0
|
479 |
|
sl@0
|
480 |
void TUsbcScBuffer::UpdateBufferList(TInt aByteCount,TUint aFlags, TBool aStartNextRead)
|
sl@0
|
481 |
{
|
sl@0
|
482 |
|
sl@0
|
483 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::UpdateBUfferLIst aByteCount %d, flags 0x%x iHead 0x%x", aByteCount, aFlags, iHead));
|
sl@0
|
484 |
|
sl@0
|
485 |
TInt headerSize = sizeof(TUsbcScTransferHeader)-4; // TransferHeader includes 4 bytes of data.
|
sl@0
|
486 |
TLinAddr dummy;
|
sl@0
|
487 |
__KTRACE_OPT(KUSB, Kern::Printf("iHead 0x%x headerSize 0x%x",iHead, headerSize));
|
sl@0
|
488 |
|
sl@0
|
489 |
// Find iNext
|
sl@0
|
490 |
|
sl@0
|
491 |
TInt next = iHead + headerSize + aByteCount; // next unused byte in buffer.
|
sl@0
|
492 |
TInt maxLength;
|
sl@0
|
493 |
|
sl@0
|
494 |
// This may take a few loops before we settle on a value.
|
sl@0
|
495 |
do
|
sl@0
|
496 |
{
|
sl@0
|
497 |
// round up.
|
sl@0
|
498 |
next = (next + headerSize + ~iAlignMask) & iAlignMask;
|
sl@0
|
499 |
maxLength = iChunkInfo->GetPhysical(next, &dummy);
|
sl@0
|
500 |
|
sl@0
|
501 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::UpdateBUfferLIst next %x buffer end %x min-read: %x maxRun %x", next, iBufferEnd, iMinReadSize, maxLength));
|
sl@0
|
502 |
// At the end of the buffer - wrap it if needbe.
|
sl@0
|
503 |
if ((TUint)(next + iMinReadSize) > iBufferEnd)
|
sl@0
|
504 |
{
|
sl@0
|
505 |
next = iFirstPacket;
|
sl@0
|
506 |
continue;
|
sl@0
|
507 |
}
|
sl@0
|
508 |
// Not enough space, move onto next block.
|
sl@0
|
509 |
if (maxLength<iMinReadSize)
|
sl@0
|
510 |
{
|
sl@0
|
511 |
next+=maxLength;
|
sl@0
|
512 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::UpdateBUfferLIst Skip exhausted block. next %x max %d", next, maxLength));
|
sl@0
|
513 |
continue;
|
sl@0
|
514 |
}
|
sl@0
|
515 |
}
|
sl@0
|
516 |
while (EFalse);
|
sl@0
|
517 |
|
sl@0
|
518 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::UpdateBUfferLIst next (pre deduct): %x, Fill in header at head: 0x%x, BuffStart: 0x%x.", next, iHead, iBufferStart));
|
sl@0
|
519 |
|
sl@0
|
520 |
next -= headerSize; // Move next back from the data start position, to the header start.
|
sl@0
|
521 |
|
sl@0
|
522 |
TUsbcScTransferHeader* header = (TUsbcScTransferHeader*) (iHead + iChunkAddr);
|
sl@0
|
523 |
|
sl@0
|
524 |
// Create Header
|
sl@0
|
525 |
#ifdef _DEBUG
|
sl@0
|
526 |
header->iHashId=59*(iLdd->iAlternateSetting+1)+iCallback->iRealEpNum; // Alt setting realated....
|
sl@0
|
527 |
header->iSequence=iSequence;
|
sl@0
|
528 |
iSequence++;
|
sl@0
|
529 |
#endif
|
sl@0
|
530 |
header->iBytes=aByteCount;
|
sl@0
|
531 |
header->iNext=next;
|
sl@0
|
532 |
header->iAltSettingSeq=iLdd->iAsSeq;
|
sl@0
|
533 |
header->iAltSetting=iLdd->iAlternateSetting;
|
sl@0
|
534 |
header->iFlags=aFlags;
|
sl@0
|
535 |
__KTRACE_OPT(KUSB, Kern::Printf("We set next to 0x%x", next));
|
sl@0
|
536 |
|
sl@0
|
537 |
iStatusList.iState=ENotRunning;
|
sl@0
|
538 |
if (next==iBufferStart->iTail) //or (othwise is as good as full)
|
sl@0
|
539 |
{
|
sl@0
|
540 |
iStalled=next;
|
sl@0
|
541 |
}
|
sl@0
|
542 |
else
|
sl@0
|
543 |
{
|
sl@0
|
544 |
|
sl@0
|
545 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::UpdateBUfferLIst StartRead?? "));
|
sl@0
|
546 |
TInt oldHead=iHead;
|
sl@0
|
547 |
iHead = next;
|
sl@0
|
548 |
|
sl@0
|
549 |
if ((aStartNextRead) && (StartDataRead() == KErrOverflow))
|
sl@0
|
550 |
{ // Oh crumbs, set state as slalled.
|
sl@0
|
551 |
if (oldHead != iBufferStart->iBilTail)
|
sl@0
|
552 |
// If user has not read everything in the buffer
|
sl@0
|
553 |
// then set up a stall, so that ldd get to be woken early
|
sl@0
|
554 |
{
|
sl@0
|
555 |
iStalled=next;
|
sl@0
|
556 |
iHead=oldHead;
|
sl@0
|
557 |
}
|
sl@0
|
558 |
else // otherwise if everything is read
|
sl@0
|
559 |
// no choice but to return what we have
|
sl@0
|
560 |
{
|
sl@0
|
561 |
iBufferStart->iHead = iHead;
|
sl@0
|
562 |
}
|
sl@0
|
563 |
}
|
sl@0
|
564 |
else
|
sl@0
|
565 |
{
|
sl@0
|
566 |
iBufferStart->iHead = next;
|
sl@0
|
567 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::UpdateBUfferLIst Compleating\n"));
|
sl@0
|
568 |
}
|
sl@0
|
569 |
// Complete userside
|
sl@0
|
570 |
iStatusList.Complete();
|
sl@0
|
571 |
}
|
sl@0
|
572 |
}
|
sl@0
|
573 |
|
sl@0
|
574 |
void TUsbcScBuffer::PopStall()
|
sl@0
|
575 |
{
|
sl@0
|
576 |
if (iStalled==iBufferStart->iTail)
|
sl@0
|
577 |
return; // Still stalled.
|
sl@0
|
578 |
|
sl@0
|
579 |
if (iStalled!=-1) // If not Alt packet only stall
|
sl@0
|
580 |
{
|
sl@0
|
581 |
// pop off packet
|
sl@0
|
582 |
iHead = iStalled;
|
sl@0
|
583 |
}
|
sl@0
|
584 |
iStalled=0;
|
sl@0
|
585 |
// If Alt setting of the popped packet is different to now
|
sl@0
|
586 |
// Add alt setting change packet.
|
sl@0
|
587 |
|
sl@0
|
588 |
|
sl@0
|
589 |
if (StartDataRead() == KErrOverflow)
|
sl@0
|
590 |
{
|
sl@0
|
591 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::PopStall Warning: Transfer was freed, but still no space!\n"));
|
sl@0
|
592 |
}
|
sl@0
|
593 |
|
sl@0
|
594 |
iBufferStart->iHead = iHead;
|
sl@0
|
595 |
}
|
sl@0
|
596 |
|
sl@0
|
597 |
|
sl@0
|
598 |
|
sl@0
|
599 |
void TUsbcScBuffer::StartDataWrite()
|
sl@0
|
600 |
{
|
sl@0
|
601 |
|
sl@0
|
602 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartDataWrite()"));
|
sl@0
|
603 |
TUsbcScStatusElement* nextJob = iStatusList.Next();
|
sl@0
|
604 |
TBool zlpReqd;
|
sl@0
|
605 |
TInt length;
|
sl@0
|
606 |
TUint start;
|
sl@0
|
607 |
TUint8* startAddr;
|
sl@0
|
608 |
TInt maxLength;
|
sl@0
|
609 |
TPhysAddr physAddr;
|
sl@0
|
610 |
TInt r;
|
sl@0
|
611 |
if (!iMaxPacketSize)
|
sl@0
|
612 |
{
|
sl@0
|
613 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartDataWrite() - Not Configured"));
|
sl@0
|
614 |
return;
|
sl@0
|
615 |
}
|
sl@0
|
616 |
|
sl@0
|
617 |
if (nextJob == NULL)
|
sl@0
|
618 |
{
|
sl@0
|
619 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartDataWrite() - No more jobs d=%d", iDirection));
|
sl@0
|
620 |
if (iDirection==KUsbcScBiIn) // assume this is EP0, if this is true.
|
sl@0
|
621 |
{
|
sl@0
|
622 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::StartDataWrite() Queue Read on EP0."));
|
sl@0
|
623 |
// Start other read again.
|
sl@0
|
624 |
iLdd->iBuffers[iLdd->iEP0OutBuff].StartDataRead();
|
sl@0
|
625 |
}
|
sl@0
|
626 |
}
|
sl@0
|
627 |
else
|
sl@0
|
628 |
{
|
sl@0
|
629 |
if (iStatusList.iState==ENotRunning)
|
sl@0
|
630 |
iSent=0;
|
sl@0
|
631 |
iStatusList.iState=EInProgress;
|
sl@0
|
632 |
|
sl@0
|
633 |
start = nextJob->iStart;
|
sl@0
|
634 |
startAddr = (TUint8*) (start + ((TUint) (iChunkInfo->iChunkMem)));
|
sl@0
|
635 |
|
sl@0
|
636 |
length = nextJob->iLength;
|
sl@0
|
637 |
zlpReqd = (nextJob->iFlags & KUsbcScWriteFlagsZlp) !=0;
|
sl@0
|
638 |
// get max read length
|
sl@0
|
639 |
maxLength = iChunkInfo->GetPhysical( start, &physAddr);
|
sl@0
|
640 |
|
sl@0
|
641 |
if (maxLength < length)
|
sl@0
|
642 |
{
|
sl@0
|
643 |
// modify request.
|
sl@0
|
644 |
nextJob->iStart += maxLength;
|
sl@0
|
645 |
nextJob->iLength -= maxLength;
|
sl@0
|
646 |
// start this request.
|
sl@0
|
647 |
iStatusList.iState=EFramgementInProgress;
|
sl@0
|
648 |
zlpReqd=EFalse;
|
sl@0
|
649 |
length = maxLength;
|
sl@0
|
650 |
}
|
sl@0
|
651 |
|
sl@0
|
652 |
if (iDirection==KUsbcScBiIn) // this is for EP0
|
sl@0
|
653 |
{
|
sl@0
|
654 |
iLdd->iController->CancelReadBuffer(iLdd, iCallback->iRealEpNum);
|
sl@0
|
655 |
iLdd->iBuffers[iLdd->iEP0OutBuff].iStatusList.iState=ENotRunning;
|
sl@0
|
656 |
}
|
sl@0
|
657 |
|
sl@0
|
658 |
iCallback->SetTxBufferInfo(startAddr, physAddr, length);
|
sl@0
|
659 |
iCallback->iZlpReqd = zlpReqd;
|
sl@0
|
660 |
r = iLdd->iController->SetupWriteBuffer(*iCallback);
|
sl@0
|
661 |
if (r!=KErrNone)
|
sl@0
|
662 |
{
|
sl@0
|
663 |
__KTRACE_OPT(KUSB, Kern::Printf("SetupWriteBUffer Error: %d",r));
|
sl@0
|
664 |
iStatusList.Complete(r);
|
sl@0
|
665 |
}
|
sl@0
|
666 |
}
|
sl@0
|
667 |
|
sl@0
|
668 |
}
|
sl@0
|
669 |
|
sl@0
|
670 |
void TUsbcScBuffer::CompleteWrite()
|
sl@0
|
671 |
{
|
sl@0
|
672 |
TInt error = iCallback->iError;
|
sl@0
|
673 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::CompleteWrite buff=%x, err=%d",this, error));
|
sl@0
|
674 |
iSent+= iCallback->iTxBytes;
|
sl@0
|
675 |
|
sl@0
|
676 |
// More to send?
|
sl@0
|
677 |
if (error || iStatusList.iState!=EFramgementInProgress)
|
sl@0
|
678 |
{
|
sl@0
|
679 |
// complete request with error (if one).
|
sl@0
|
680 |
// Some data could have been transmitted, even with an error.
|
sl@0
|
681 |
iStatusList.Complete(error);
|
sl@0
|
682 |
}
|
sl@0
|
683 |
|
sl@0
|
684 |
// Start next request, or next part of this one.
|
sl@0
|
685 |
StartDataWrite();
|
sl@0
|
686 |
|
sl@0
|
687 |
}
|
sl@0
|
688 |
|
sl@0
|
689 |
// Cancels the current request's callback.
|
sl@0
|
690 |
// This is not to say it will cancel the actual operation,
|
sl@0
|
691 |
// However it will cancel any further sections of the user perceived operation
|
sl@0
|
692 |
// that are not yet started.
|
sl@0
|
693 |
void TUsbcScBuffer::Cancel(TInt aErrorCode)
|
sl@0
|
694 |
{
|
sl@0
|
695 |
iStatusList.CancelQueued();
|
sl@0
|
696 |
if (iLdd->iController && ((iDirection&1)==KUsbcScIn))
|
sl@0
|
697 |
{
|
sl@0
|
698 |
iLdd->iController->CancelWriteBuffer(iLdd, iCallback->iRealEpNum);
|
sl@0
|
699 |
}
|
sl@0
|
700 |
|
sl@0
|
701 |
iStatusList.Complete(aErrorCode);
|
sl@0
|
702 |
}
|
sl@0
|
703 |
|
sl@0
|
704 |
void TUsbcScBuffer::Ep0CancelLddRead()
|
sl@0
|
705 |
{
|
sl@0
|
706 |
// Stopping a read isn't as easy as one might think.
|
sl@0
|
707 |
// We cancel the callback, but then check if any data was received (but not returned to us).
|
sl@0
|
708 |
// If so, we must de-queue the request, and call the completion code.
|
sl@0
|
709 |
|
sl@0
|
710 |
iLdd->iController->CancelReadBuffer(iLdd, iCallback->iRealEpNum);
|
sl@0
|
711 |
if (iCallback->iRxPackets) // received data?
|
sl@0
|
712 |
{
|
sl@0
|
713 |
// remove DFC (if infact sent)
|
sl@0
|
714 |
iCallback->iDfc.Cancel();
|
sl@0
|
715 |
|
sl@0
|
716 |
// process the callback now, but dont start another
|
sl@0
|
717 |
CompleteRead(EFalse);
|
sl@0
|
718 |
}
|
sl@0
|
719 |
}
|
sl@0
|
720 |
|
sl@0
|
721 |
void TUsbcScBuffer::SendEp0StatusPacket(TInt aState)
|
sl@0
|
722 |
{
|
sl@0
|
723 |
__KTRACE_OPT(KUSB, Kern::Printf(" TUsbcScBuffer::SendEp0StatusPacket(%d)", aState));
|
sl@0
|
724 |
|
sl@0
|
725 |
// We need to add a packet to the buffer, so we must stop the pending read, and start
|
sl@0
|
726 |
// another after we have added out packet.
|
sl@0
|
727 |
Ep0CancelLddRead();
|
sl@0
|
728 |
|
sl@0
|
729 |
TUint* state = ((TUsbcScTransferHeader *) (iHead + iChunkAddr))->iData.i;
|
sl@0
|
730 |
*state = aState;
|
sl@0
|
731 |
UpdateBufferList(4,KUsbcScStateChange);
|
sl@0
|
732 |
}
|
sl@0
|
733 |
|
sl@0
|
734 |
// End TUsbcScBuffer
|
sl@0
|
735 |
|
sl@0
|
736 |
/*****************************************************************************\
|
sl@0
|
737 |
* TUsbcScStatusList *
|
sl@0
|
738 |
* *
|
sl@0
|
739 |
* This is a list of read or write requests, containing user status *
|
sl@0
|
740 |
* requests, that should later be completed. *
|
sl@0
|
741 |
* *
|
sl@0
|
742 |
\*****************************************************************************/
|
sl@0
|
743 |
|
sl@0
|
744 |
/**
|
sl@0
|
745 |
Constructor for TUsbcScStatusList.
|
sl@0
|
746 |
|
sl@0
|
747 |
@param aSize is the number of requests to allow at any one time. This value
|
sl@0
|
748 |
must be a power of two, for correct operation.
|
sl@0
|
749 |
|
sl@0
|
750 |
@returns KErrNoMemory if memory allocation failure, otherwise KErrNone.
|
sl@0
|
751 |
*/
|
sl@0
|
752 |
|
sl@0
|
753 |
TInt TUsbcScStatusList::Construct(TInt aSize, DThread* aClient)
|
sl@0
|
754 |
{
|
sl@0
|
755 |
iSize=aSize;
|
sl@0
|
756 |
iHead = 0;
|
sl@0
|
757 |
iLength = 0;
|
sl@0
|
758 |
iClient = aClient;
|
sl@0
|
759 |
iElements=(TUsbcScStatusElement *) Kern::AllocZ(sizeof(TUsbcScStatusElement)*aSize);
|
sl@0
|
760 |
return (iElements==NULL)?KErrNoMemory:KErrNone;
|
sl@0
|
761 |
};
|
sl@0
|
762 |
|
sl@0
|
763 |
|
sl@0
|
764 |
// StatusList must be inactive before destroying.
|
sl@0
|
765 |
void TUsbcScStatusList::Destroy()
|
sl@0
|
766 |
{
|
sl@0
|
767 |
if (iState!=ENotRunning)
|
sl@0
|
768 |
Kern::Fault("TUsbcScStatusList::Destroy", __LINE__);
|
sl@0
|
769 |
if (iElements)
|
sl@0
|
770 |
{
|
sl@0
|
771 |
Kern::Free(iElements);
|
sl@0
|
772 |
iElements=NULL;
|
sl@0
|
773 |
}
|
sl@0
|
774 |
iClient=NULL;
|
sl@0
|
775 |
}
|
sl@0
|
776 |
|
sl@0
|
777 |
void TUsbcScStatusList::Pop()
|
sl@0
|
778 |
{
|
sl@0
|
779 |
if (iLength>0)
|
sl@0
|
780 |
{
|
sl@0
|
781 |
iLength--;
|
sl@0
|
782 |
iHead = ((iHead+1) & (iSize-1));
|
sl@0
|
783 |
}
|
sl@0
|
784 |
}
|
sl@0
|
785 |
|
sl@0
|
786 |
TUsbcScStatusElement* TUsbcScStatusList::Next()
|
sl@0
|
787 |
{
|
sl@0
|
788 |
return (iLength==0)?NULL:&(iElements[iHead]);
|
sl@0
|
789 |
}
|
sl@0
|
790 |
|
sl@0
|
791 |
TInt TUsbcScStatusList ::Add(TRequestStatus* aStatus, TInt aLength, TUint aStart, TUint aFlags)
|
sl@0
|
792 |
{
|
sl@0
|
793 |
__KTRACE_OPT(KUSB,Kern::Printf("Adding request. iLength %d iSize %d", iLength, iSize));
|
sl@0
|
794 |
if (iLength<iSize)
|
sl@0
|
795 |
{
|
sl@0
|
796 |
TUsbcScStatusElement& e = iElements[((iHead+iLength) & (iSize-1))];
|
sl@0
|
797 |
e.iStatus = aStatus;
|
sl@0
|
798 |
e.iLength = aLength;
|
sl@0
|
799 |
e.iStart = aStart;
|
sl@0
|
800 |
e.iFlags = aFlags;
|
sl@0
|
801 |
iLength++;
|
sl@0
|
802 |
__KTRACE_OPT(KUSB,Kern::Printf("Adding request. new iLength %d", iLength));
|
sl@0
|
803 |
|
sl@0
|
804 |
return KErrNone;
|
sl@0
|
805 |
}
|
sl@0
|
806 |
else
|
sl@0
|
807 |
return KErrInUse;
|
sl@0
|
808 |
}
|
sl@0
|
809 |
|
sl@0
|
810 |
|
sl@0
|
811 |
|
sl@0
|
812 |
// This method cancels any requests that have yet to be started.
|
sl@0
|
813 |
|
sl@0
|
814 |
void TUsbcScStatusList::CancelQueued(TInt aError)
|
sl@0
|
815 |
{
|
sl@0
|
816 |
if ((iLength==0) || ((iState!=ENotRunning) && (iLength==1))) // Nothing to do.
|
sl@0
|
817 |
return;
|
sl@0
|
818 |
TInt elements2Complete = iLength - (iState?1:0);
|
sl@0
|
819 |
TInt head = iHead;
|
sl@0
|
820 |
iLength = 0;
|
sl@0
|
821 |
if (iState) // If (iState != ENotRunning), complete all elements excepting the one at head
|
sl@0
|
822 |
{
|
sl@0
|
823 |
head = ((head+1) & (iSize-1)); // To iterate through the queue
|
sl@0
|
824 |
iLength = 1;
|
sl@0
|
825 |
}
|
sl@0
|
826 |
// complete them all.
|
sl@0
|
827 |
for (; elements2Complete>0; elements2Complete--)
|
sl@0
|
828 |
{
|
sl@0
|
829 |
Kern::RequestComplete(iClient, iElements[head].iStatus, aError);
|
sl@0
|
830 |
head = ((head+1) & (iSize-1));
|
sl@0
|
831 |
}
|
sl@0
|
832 |
|
sl@0
|
833 |
}
|
sl@0
|
834 |
|
sl@0
|
835 |
|
sl@0
|
836 |
/* This method Completes the head status request, and pops it from its list.
|
sl@0
|
837 |
This version of Complete is to be used in cases where the next request is not
|
sl@0
|
838 |
chained - usually because of an error.
|
sl@0
|
839 |
|
sl@0
|
840 |
@Param aError - the code to complete with.
|
sl@0
|
841 |
|
sl@0
|
842 |
returns KErrNotFound if there was no request to complete
|
sl@0
|
843 |
*/
|
sl@0
|
844 |
|
sl@0
|
845 |
|
sl@0
|
846 |
TInt TUsbcScStatusList::Complete(TInt aError)
|
sl@0
|
847 |
{
|
sl@0
|
848 |
if (iState==ENotRunning)
|
sl@0
|
849 |
{
|
sl@0
|
850 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScStatusList::Complete() - iState == ENotRunning!"));
|
sl@0
|
851 |
}
|
sl@0
|
852 |
else
|
sl@0
|
853 |
{
|
sl@0
|
854 |
iState=ENotRunning;
|
sl@0
|
855 |
if (iLength==0)
|
sl@0
|
856 |
return KErrNotFound;
|
sl@0
|
857 |
|
sl@0
|
858 |
Kern::RequestComplete(iClient, iElements[iHead].iStatus, aError);
|
sl@0
|
859 |
|
sl@0
|
860 |
iLength--;
|
sl@0
|
861 |
iHead = ((iHead+1) & (iSize-1));
|
sl@0
|
862 |
}
|
sl@0
|
863 |
return KErrNone;
|
sl@0
|
864 |
}
|
sl@0
|
865 |
|
sl@0
|
866 |
|
sl@0
|
867 |
/* This method Completes the head status request, and pops it from its list. (If found.)
|
sl@0
|
868 |
This version of Complete is to be used in cases where the request is successful, and
|
sl@0
|
869 |
next request after this has (if present) been chained.
|
sl@0
|
870 |
*/
|
sl@0
|
871 |
|
sl@0
|
872 |
void TUsbcScStatusList::Complete()
|
sl@0
|
873 |
{
|
sl@0
|
874 |
if (iLength==0)
|
sl@0
|
875 |
return;
|
sl@0
|
876 |
__KTRACE_OPT(KUSB, Kern::Printf("Completing request. iLength %d", iLength));
|
sl@0
|
877 |
|
sl@0
|
878 |
Kern::RequestComplete(iClient, iElements[iHead].iStatus, KErrNone);
|
sl@0
|
879 |
|
sl@0
|
880 |
iLength--;
|
sl@0
|
881 |
iHead = ((iHead+1) & (iSize-1));
|
sl@0
|
882 |
}
|
sl@0
|
883 |
|
sl@0
|
884 |
// End TUsbcScStatusList
|
sl@0
|
885 |
|
sl@0
|
886 |
/*****************************************************************************\
|
sl@0
|
887 |
* TRealizeInfo *
|
sl@0
|
888 |
* *
|
sl@0
|
889 |
* Used by DLddUsbcScChannel::RealizeInterface to set up the chunk *
|
sl@0
|
890 |
* *
|
sl@0
|
891 |
\*****************************************************************************/
|
sl@0
|
892 |
|
sl@0
|
893 |
// Init
|
sl@0
|
894 |
//
|
sl@0
|
895 |
// This method works out the number potential maximum number of endpoints
|
sl@0
|
896 |
// and the number of alt settings. With this information it allocs
|
sl@0
|
897 |
// the necessary space for the given stucture to store information about
|
sl@0
|
898 |
// the endpoints.
|
sl@0
|
899 |
// This is intended to be called by RealizeInterface. This stucture is
|
sl@0
|
900 |
// intended to be only temporary, and the space will be freed with Free()
|
sl@0
|
901 |
// before RealizeInteface has finished.
|
sl@0
|
902 |
|
sl@0
|
903 |
void TRealizeInfo::Init(TUsbcScAlternateSettingList* aAlternateSettingList)
|
sl@0
|
904 |
{
|
sl@0
|
905 |
iAlternateSettingList = aAlternateSettingList;
|
sl@0
|
906 |
iMaxEndpoints=0;
|
sl@0
|
907 |
iTotalSize =0;
|
sl@0
|
908 |
iTotalBuffers=0;
|
sl@0
|
909 |
iAltSettings =0;
|
sl@0
|
910 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: work out max endpoint"));
|
sl@0
|
911 |
// Work out max endpoints and number of alternate settings.
|
sl@0
|
912 |
|
sl@0
|
913 |
if (iAlternateSettingList)
|
sl@0
|
914 |
{
|
sl@0
|
915 |
TUsbcScAlternateSetting* alt = iAlternateSettingList->iHead;
|
sl@0
|
916 |
while (alt != NULL)
|
sl@0
|
917 |
{
|
sl@0
|
918 |
iAltSettings++;
|
sl@0
|
919 |
if (alt->iNumberOfEndpoints>iMaxEndpoints)
|
sl@0
|
920 |
iMaxEndpoints = alt->iNumberOfEndpoints;
|
sl@0
|
921 |
// could work out in/out specifics, but unnecessary.
|
sl@0
|
922 |
alt = alt->iNext;
|
sl@0
|
923 |
};
|
sl@0
|
924 |
}
|
sl@0
|
925 |
|
sl@0
|
926 |
// Alloc some temporary working space for temp endpoint metadata
|
sl@0
|
927 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Alloc temp. Maxendpoints %d", iMaxEndpoints));
|
sl@0
|
928 |
TInt inout;
|
sl@0
|
929 |
for (inout=KUsbcScIn; inout<KUsbcScDirections; inout++)
|
sl@0
|
930 |
{
|
sl@0
|
931 |
iBufs[inout].iEp = (TUsbcScEndpoint **) Kern::AllocZ(iAltSettings*iMaxEndpoints*sizeof(TUsbcScEndpoint *));
|
sl@0
|
932 |
iBufs[inout].iSizes = (TInt *) Kern::AllocZ(iMaxEndpoints*sizeof(TInt));
|
sl@0
|
933 |
}
|
sl@0
|
934 |
}
|
sl@0
|
935 |
|
sl@0
|
936 |
// CopyAndSortEndpoints
|
sl@0
|
937 |
//
|
sl@0
|
938 |
// This method copies pointers to the endpoint records into TRealizeInfo
|
sl@0
|
939 |
// such that they are sorted in order of size per alt setting.
|
sl@0
|
940 |
// In and Out endpoints are separated, and kept separate.
|
sl@0
|
941 |
// The provided data structure is assumed to have been initialised with
|
sl@0
|
942 |
// Realize_InitRealizeInfo.
|
sl@0
|
943 |
//
|
sl@0
|
944 |
// Return KErrArgument if the direction field is neither In or Out.
|
sl@0
|
945 |
//
|
sl@0
|
946 |
|
sl@0
|
947 |
TInt TRealizeInfo::CopyAndSortEndpoints()
|
sl@0
|
948 |
{
|
sl@0
|
949 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: copy And sort"));
|
sl@0
|
950 |
|
sl@0
|
951 |
TInt altSetting = 0;
|
sl@0
|
952 |
TInt endpointOffs;
|
sl@0
|
953 |
TInt endpoint;
|
sl@0
|
954 |
TInt altEp;
|
sl@0
|
955 |
TInt inout;
|
sl@0
|
956 |
TBool placed;
|
sl@0
|
957 |
TUsbcScAlternateSetting* alt;
|
sl@0
|
958 |
TEndpointSortBufs* bufsd;
|
sl@0
|
959 |
|
sl@0
|
960 |
if (iAlternateSettingList)
|
sl@0
|
961 |
{
|
sl@0
|
962 |
for (alt = iAlternateSettingList->iHead;alt!=NULL;alt = alt->iNext )
|
sl@0
|
963 |
{
|
sl@0
|
964 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: AlternateSetting %x", alt));
|
sl@0
|
965 |
|
sl@0
|
966 |
iBufs[KUsbcScIn].iEps =0;
|
sl@0
|
967 |
iBufs[KUsbcScOut].iEps =0;
|
sl@0
|
968 |
|
sl@0
|
969 |
// For alt setting, iterate eps
|
sl@0
|
970 |
for (altEp=1; altEp <= alt->iNumberOfEndpoints; altEp++)
|
sl@0
|
971 |
{
|
sl@0
|
972 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Endpoint to add: %d",altEp));
|
sl@0
|
973 |
|
sl@0
|
974 |
TUsbcScEndpoint* nextEp = alt->iEndpoint[altEp];
|
sl@0
|
975 |
|
sl@0
|
976 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: ep Buffer Size: %d",nextEp->EndpointInfo()->iBufferSize));
|
sl@0
|
977 |
|
sl@0
|
978 |
inout = (nextEp->EndpointInfo()->iDir==KUsbEpDirIn)?KUsbcScIn:
|
sl@0
|
979 |
(nextEp->EndpointInfo()->iDir==KUsbEpDirOut)?KUsbcScOut:KUsbcScUnknown;
|
sl@0
|
980 |
if (inout==KUsbcScUnknown)
|
sl@0
|
981 |
{
|
sl@0
|
982 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: KUsbcScUnknown %x",nextEp->EndpointInfo()->iDir));
|
sl@0
|
983 |
return KErrArgument;
|
sl@0
|
984 |
}
|
sl@0
|
985 |
|
sl@0
|
986 |
bufsd = &(iBufs[inout]);
|
sl@0
|
987 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: ep direction: %x # endpoints %d", inout, bufsd->iEps));
|
sl@0
|
988 |
|
sl@0
|
989 |
|
sl@0
|
990 |
// find and position ep, and insert.
|
sl@0
|
991 |
|
sl@0
|
992 |
if (bufsd->iEps==0) // First entry.
|
sl@0
|
993 |
{
|
sl@0
|
994 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Add first endpoint"));
|
sl@0
|
995 |
endpointOffs = altSetting*iMaxEndpoints;
|
sl@0
|
996 |
bufsd->iEp[endpointOffs] = nextEp;
|
sl@0
|
997 |
}
|
sl@0
|
998 |
else
|
sl@0
|
999 |
{
|
sl@0
|
1000 |
placed = EFalse;
|
sl@0
|
1001 |
// Move down the list, until we find the right place.
|
sl@0
|
1002 |
for (endpoint=bufsd->iEps-1; endpoint>-1; endpoint--)
|
sl@0
|
1003 |
{
|
sl@0
|
1004 |
endpointOffs = altSetting*iMaxEndpoints + endpoint;
|
sl@0
|
1005 |
if (bufsd->iEp[endpointOffs]->EndpointInfo()->iBufferSize < nextEp->EndpointInfo()->iBufferSize)
|
sl@0
|
1006 |
{
|
sl@0
|
1007 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Shift Endpoint %d", endpoint));
|
sl@0
|
1008 |
|
sl@0
|
1009 |
bufsd->iEp[endpointOffs+1] = bufsd->iEp[endpointOffs];
|
sl@0
|
1010 |
}
|
sl@0
|
1011 |
else
|
sl@0
|
1012 |
{
|
sl@0
|
1013 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Insert After Endpoint %d", endpoint));
|
sl@0
|
1014 |
|
sl@0
|
1015 |
bufsd->iEp[endpointOffs+1] = nextEp;
|
sl@0
|
1016 |
placed = ETrue;
|
sl@0
|
1017 |
break;
|
sl@0
|
1018 |
}
|
sl@0
|
1019 |
} // end for endpoint
|
sl@0
|
1020 |
if (!placed) // if we didn't place it, it must be the biggest so far, so goes at the top.
|
sl@0
|
1021 |
bufsd->iEp[0] = nextEp;
|
sl@0
|
1022 |
} // endif
|
sl@0
|
1023 |
bufsd->iEps++;
|
sl@0
|
1024 |
} // for altEp
|
sl@0
|
1025 |
altSetting++;
|
sl@0
|
1026 |
} // for alt
|
sl@0
|
1027 |
}// if iAltsettingList
|
sl@0
|
1028 |
return KErrNone;
|
sl@0
|
1029 |
}
|
sl@0
|
1030 |
|
sl@0
|
1031 |
// CalcBuffSizes
|
sl@0
|
1032 |
//
|
sl@0
|
1033 |
// This works out the sizes of all the buffers, and stores the result in aBufInfo
|
sl@0
|
1034 |
// based on the buffer information provided in the same structure.
|
sl@0
|
1035 |
// Realize_CopyAndSortEndpoints is used to fill the structure with the informaition
|
sl@0
|
1036 |
// required.
|
sl@0
|
1037 |
|
sl@0
|
1038 |
void TRealizeInfo::CalcBuffSizes()
|
sl@0
|
1039 |
{
|
sl@0
|
1040 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Calculate Buffers"));
|
sl@0
|
1041 |
|
sl@0
|
1042 |
TInt endpoint;
|
sl@0
|
1043 |
TInt inout;
|
sl@0
|
1044 |
TInt altSetting;
|
sl@0
|
1045 |
TUsbcScEndpoint* nextEp;
|
sl@0
|
1046 |
TInt bufferSize;
|
sl@0
|
1047 |
TEndpointSortBufs* bufsd;
|
sl@0
|
1048 |
|
sl@0
|
1049 |
for (inout=KUsbcScIn; inout<KUsbcScDirections; inout++)
|
sl@0
|
1050 |
{
|
sl@0
|
1051 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Direction: %d", inout));
|
sl@0
|
1052 |
|
sl@0
|
1053 |
|
sl@0
|
1054 |
bufsd = &(iBufs[inout]);
|
sl@0
|
1055 |
// for each row, ie, buffer, find largest buffer need.
|
sl@0
|
1056 |
for (endpoint=0; endpoint<iMaxEndpoints; endpoint++)
|
sl@0
|
1057 |
{
|
sl@0
|
1058 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: endpoint %d", endpoint));
|
sl@0
|
1059 |
TInt bufMaxSize=0;
|
sl@0
|
1060 |
for (altSetting=0; altSetting< iAltSettings; altSetting++)
|
sl@0
|
1061 |
{
|
sl@0
|
1062 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: altSetting %d", altSetting));
|
sl@0
|
1063 |
nextEp= bufsd->iEp[altSetting* iMaxEndpoints + endpoint];
|
sl@0
|
1064 |
if (nextEp!=NULL)
|
sl@0
|
1065 |
{
|
sl@0
|
1066 |
bufferSize = nextEp->EndpointInfo()->iBufferSize;
|
sl@0
|
1067 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: comparing size %d", bufferSize));
|
sl@0
|
1068 |
if (bufferSize> bufMaxSize)
|
sl@0
|
1069 |
bufMaxSize = bufferSize;
|
sl@0
|
1070 |
}
|
sl@0
|
1071 |
} // for altsetting
|
sl@0
|
1072 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: bufMaxSize %d", bufMaxSize));
|
sl@0
|
1073 |
bufsd->iSizes[endpoint] = bufMaxSize;
|
sl@0
|
1074 |
if (bufMaxSize>0)
|
sl@0
|
1075 |
{
|
sl@0
|
1076 |
iTotalSize += bufsd->iSizes[endpoint];
|
sl@0
|
1077 |
iTotalBuffers++;
|
sl@0
|
1078 |
}
|
sl@0
|
1079 |
} // for endpoint
|
sl@0
|
1080 |
} // for in/out
|
sl@0
|
1081 |
}
|
sl@0
|
1082 |
|
sl@0
|
1083 |
// Free
|
sl@0
|
1084 |
//
|
sl@0
|
1085 |
// Cleans up after Init()
|
sl@0
|
1086 |
|
sl@0
|
1087 |
void TRealizeInfo::Free()
|
sl@0
|
1088 |
{
|
sl@0
|
1089 |
TInt inout;
|
sl@0
|
1090 |
for (inout=KUsbcScIn; inout<KUsbcScDirections; inout++)
|
sl@0
|
1091 |
{
|
sl@0
|
1092 |
Kern::Free(iBufs[inout].iEp);
|
sl@0
|
1093 |
Kern::Free(iBufs[inout].iSizes);
|
sl@0
|
1094 |
}
|
sl@0
|
1095 |
}
|
sl@0
|
1096 |
|
sl@0
|
1097 |
// End TRealizeInfo
|
sl@0
|
1098 |
|
sl@0
|
1099 |
|
sl@0
|
1100 |
// LayoutChunkHeader
|
sl@0
|
1101 |
//
|
sl@0
|
1102 |
// Sets up some geometry for the chunk;
|
sl@0
|
1103 |
|
sl@0
|
1104 |
void TRealizeInfo::LayoutChunkHeader(TUsbcScChunkInfo* aChunkInfo)
|
sl@0
|
1105 |
{
|
sl@0
|
1106 |
// First set up the indexes to the header structures.
|
sl@0
|
1107 |
TUsbcScChunkHdrOffs* chkHdr = (TUsbcScChunkHdrOffs*) aChunkInfo->iChunkMem;
|
sl@0
|
1108 |
|
sl@0
|
1109 |
chkHdr->iBuffers = sizeof(TUsbcScChunkHdrOffs); // First struct just after this one.
|
sl@0
|
1110 |
iChunkStuct = (TUsbcScChunkBuffersHeader*) ( (TInt) aChunkInfo->iChunkMem + chkHdr->iBuffers);
|
sl@0
|
1111 |
|
sl@0
|
1112 |
// Store number of buffers in chunk
|
sl@0
|
1113 |
iChunkStuct->iRecordSize = sizeof(TUsbcScBufferRecord);
|
sl@0
|
1114 |
iChunkStuct->iNumOfBufs=iTotalBuffers;
|
sl@0
|
1115 |
|
sl@0
|
1116 |
iAltSettingsTbl = (TUsbcScChunkAltSettingHeader*) &(iChunkStuct->iBufferOffset[(iTotalBuffers+2)*sizeof(TUsbcScBufferRecord)]); // 2 extra for EP0 in and out.
|
sl@0
|
1117 |
|
sl@0
|
1118 |
chkHdr->iAltSettings = (TUint) iAltSettingsTbl - (TUint) aChunkInfo->iChunkMem;
|
sl@0
|
1119 |
|
sl@0
|
1120 |
iAltSettingsTbl->iEpRecordSize = sizeof(TUint);
|
sl@0
|
1121 |
iAltSettingsTbl->iNumOfAltSettings = iAltSettings;
|
sl@0
|
1122 |
|
sl@0
|
1123 |
|
sl@0
|
1124 |
TInt tableOffset = (TUint) iAltSettingsTbl->iAltTableOffset - (TUint) aChunkInfo->iChunkMem + iAltSettings*sizeof(TInt);
|
sl@0
|
1125 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: table offset: 0x%x, altTble %x iChnkMem %x altSettings %x",tableOffset, iAltSettingsTbl, aChunkInfo->iChunkMem, iAltSettings ));
|
sl@0
|
1126 |
|
sl@0
|
1127 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: populate chunk - create alt settings table"));
|
sl@0
|
1128 |
|
sl@0
|
1129 |
// Create alt settings table. Set each element of altsettings table, to each induivatual alt setting table.
|
sl@0
|
1130 |
// then fill in the number of endpoints for that alt setting, in the table.
|
sl@0
|
1131 |
|
sl@0
|
1132 |
TInt* noEpForAlt;
|
sl@0
|
1133 |
TInt altSetting;
|
sl@0
|
1134 |
TUsbcScAlternateSetting* alt;
|
sl@0
|
1135 |
if (iAlternateSettingList)
|
sl@0
|
1136 |
{
|
sl@0
|
1137 |
alt = iAlternateSettingList->iHead;
|
sl@0
|
1138 |
for (altSetting=0; altSetting<iAltSettings; altSetting++)
|
sl@0
|
1139 |
{
|
sl@0
|
1140 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: altSetting %d, tableOffset %d", altSetting, tableOffset));
|
sl@0
|
1141 |
|
sl@0
|
1142 |
iAltSettingsTbl->iAltTableOffset[altSetting] = tableOffset;
|
sl@0
|
1143 |
noEpForAlt = (TInt*) &aChunkInfo->iChunkMem[tableOffset];
|
sl@0
|
1144 |
|
sl@0
|
1145 |
*noEpForAlt = alt->iNumberOfEndpoints; // Set NumberofEndpoints field in Altsetting table
|
sl@0
|
1146 |
tableOffset+= sizeof(TInt)+ alt->iNumberOfEndpoints*sizeof(TUsbcScHdrEndpointRecord);
|
sl@0
|
1147 |
alt = alt->iNext;
|
sl@0
|
1148 |
}
|
sl@0
|
1149 |
}
|
sl@0
|
1150 |
|
sl@0
|
1151 |
} // end LayoutChunkHeader
|
sl@0
|
1152 |
|
sl@0
|
1153 |
|
sl@0
|
1154 |
|
sl@0
|
1155 |
/*****************************************************************************\
|
sl@0
|
1156 |
* DLddUsbcScChannel *
|
sl@0
|
1157 |
* *
|
sl@0
|
1158 |
* Inherits from DLogicalDevice, the USB Shared Chunk LDD factory class *
|
sl@0
|
1159 |
* *
|
sl@0
|
1160 |
\*****************************************************************************/
|
sl@0
|
1161 |
|
sl@0
|
1162 |
//
|
sl@0
|
1163 |
// Constructor
|
sl@0
|
1164 |
//
|
sl@0
|
1165 |
DLddUsbcScChannel::DLddUsbcScChannel()
|
sl@0
|
1166 |
: iValidInterface(EFalse),
|
sl@0
|
1167 |
iAlternateSettingList(NULL),
|
sl@0
|
1168 |
iEndpoint(NULL),
|
sl@0
|
1169 |
iCompleteAllCallbackInfo(this, DLddUsbcScChannel::EmergencyCompleteDfc, KUsbRequestCallbackPriority),
|
sl@0
|
1170 |
iStatusChangePtr(NULL),
|
sl@0
|
1171 |
iStatusCallbackInfo(this, DLddUsbcScChannel::StatusChangeCallback, KUsbRequestCallbackPriority),
|
sl@0
|
1172 |
iEndpointStatusChangePtr(NULL),
|
sl@0
|
1173 |
iEndpointStatusCallbackInfo(this, DLddUsbcScChannel::EndpointStatusChangeCallback,
|
sl@0
|
1174 |
KUsbRequestCallbackPriority),
|
sl@0
|
1175 |
iOtgFeatureChangePtr(NULL),
|
sl@0
|
1176 |
iOtgFeatureCallbackInfo(this, DLddUsbcScChannel::OtgFeatureChangeCallback, KUsbRequestCallbackPriority),
|
sl@0
|
1177 |
iNumberOfEndpoints(0),
|
sl@0
|
1178 |
iDeviceState(EUsbcDeviceStateUndefined),
|
sl@0
|
1179 |
iOwnsDeviceControl(EFalse),
|
sl@0
|
1180 |
iAlternateSetting(0),
|
sl@0
|
1181 |
iAsSeq(0),
|
sl@0
|
1182 |
iStatusFifo(NULL),
|
sl@0
|
1183 |
iUserKnowsAltSetting(ETrue),
|
sl@0
|
1184 |
iDeviceStatusNeeded(EFalse),
|
sl@0
|
1185 |
iChannelClosing(EFalse),
|
sl@0
|
1186 |
iRealizeCalled(EFalse),
|
sl@0
|
1187 |
iChunkInfo(NULL),
|
sl@0
|
1188 |
iNumBuffers(-1),
|
sl@0
|
1189 |
iBuffers(NULL),
|
sl@0
|
1190 |
iEp0Endpoint(NULL)
|
sl@0
|
1191 |
{
|
sl@0
|
1192 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::DLddUsbcScChannel()"));
|
sl@0
|
1193 |
iClient = &Kern::CurrentThread();
|
sl@0
|
1194 |
iClient->Open();
|
sl@0
|
1195 |
for (TInt i = 1; i < KUsbcMaxRequests; i++)
|
sl@0
|
1196 |
{
|
sl@0
|
1197 |
iRequestStatus[i] = NULL;
|
sl@0
|
1198 |
}
|
sl@0
|
1199 |
}
|
sl@0
|
1200 |
|
sl@0
|
1201 |
|
sl@0
|
1202 |
//
|
sl@0
|
1203 |
// Destructor
|
sl@0
|
1204 |
//
|
sl@0
|
1205 |
|
sl@0
|
1206 |
DLddUsbcScChannel::~DLddUsbcScChannel()
|
sl@0
|
1207 |
{
|
sl@0
|
1208 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::~DLddUsbcScChannel()"));
|
sl@0
|
1209 |
if (iController)
|
sl@0
|
1210 |
{
|
sl@0
|
1211 |
iStatusCallbackInfo.Cancel();
|
sl@0
|
1212 |
iEndpointStatusCallbackInfo.Cancel();
|
sl@0
|
1213 |
iOtgFeatureCallbackInfo.Cancel();
|
sl@0
|
1214 |
iCompleteAllCallbackInfo.Cancel();
|
sl@0
|
1215 |
DestroyAllInterfaces();
|
sl@0
|
1216 |
if (iOwnsDeviceControl)
|
sl@0
|
1217 |
{
|
sl@0
|
1218 |
iController->ReleaseDeviceControl(this);
|
sl@0
|
1219 |
iOwnsDeviceControl = EFalse;
|
sl@0
|
1220 |
}
|
sl@0
|
1221 |
iController->DeRegisterClient(this);
|
sl@0
|
1222 |
iController=NULL;
|
sl@0
|
1223 |
DestroyEp0();
|
sl@0
|
1224 |
if (iStatusFifo!=NULL)
|
sl@0
|
1225 |
{
|
sl@0
|
1226 |
delete iStatusFifo;
|
sl@0
|
1227 |
}
|
sl@0
|
1228 |
}
|
sl@0
|
1229 |
__KTRACE_OPT(KUSB, Kern::Printf("Closing buffers"));
|
sl@0
|
1230 |
if (iBuffers)
|
sl@0
|
1231 |
{
|
sl@0
|
1232 |
TInt i;
|
sl@0
|
1233 |
for (i=0; i<(iNumBuffers+2); i++)
|
sl@0
|
1234 |
{
|
sl@0
|
1235 |
iBuffers[i].Destroy();
|
sl@0
|
1236 |
}
|
sl@0
|
1237 |
Kern::Free(iBuffers);
|
sl@0
|
1238 |
}
|
sl@0
|
1239 |
|
sl@0
|
1240 |
if (iRealizeCalled)
|
sl@0
|
1241 |
{
|
sl@0
|
1242 |
// Close Chunk
|
sl@0
|
1243 |
iChunkInfo->Close();
|
sl@0
|
1244 |
// ChunkInfo will delete itself with DFC, but the pointer here is no longer needed.
|
sl@0
|
1245 |
iChunkInfo=NULL;
|
sl@0
|
1246 |
}
|
sl@0
|
1247 |
__KTRACE_OPT(KUSB, Kern::Printf("about to SafeClose"));
|
sl@0
|
1248 |
Kern::SafeClose((DObject*&)iClient, NULL);
|
sl@0
|
1249 |
}
|
sl@0
|
1250 |
|
sl@0
|
1251 |
|
sl@0
|
1252 |
//
|
sl@0
|
1253 |
// DoCreate - Create channel
|
sl@0
|
1254 |
//
|
sl@0
|
1255 |
|
sl@0
|
1256 |
TInt DLddUsbcScChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
|
sl@0
|
1257 |
{
|
sl@0
|
1258 |
__KTRACE_OPT(KUSB, Kern::Printf("LDD DoCreateL 1 Ver = %02d %02d %02d",
|
sl@0
|
1259 |
aVer.iMajor, aVer.iMinor, aVer.iBuild));
|
sl@0
|
1260 |
if (!Kern::CurrentThreadHasCapability(ECapabilityCommDD,
|
sl@0
|
1261 |
__PLATSEC_DIAGNOSTIC_STRING("Checked by USBCSC.LDD (USB Driver)")))
|
sl@0
|
1262 |
{
|
sl@0
|
1263 |
return KErrPermissionDenied;
|
sl@0
|
1264 |
}
|
sl@0
|
1265 |
|
sl@0
|
1266 |
iController = DUsbClientController::UsbcControllerPointer();
|
sl@0
|
1267 |
|
sl@0
|
1268 |
if (!iController)
|
sl@0
|
1269 |
{
|
sl@0
|
1270 |
return KErrGeneral;
|
sl@0
|
1271 |
}
|
sl@0
|
1272 |
|
sl@0
|
1273 |
iStatusFifo = new TUsbcDeviceStatusQueue;
|
sl@0
|
1274 |
if (iStatusFifo == NULL)
|
sl@0
|
1275 |
{
|
sl@0
|
1276 |
return KErrNoMemory;
|
sl@0
|
1277 |
}
|
sl@0
|
1278 |
|
sl@0
|
1279 |
if (!Kern::QueryVersionSupported(TVersion(KUsbcScMajorVersion, KUsbcScMinorVersion, KUsbcScBuildVersion), aVer))
|
sl@0
|
1280 |
{
|
sl@0
|
1281 |
return KErrNotSupported;
|
sl@0
|
1282 |
}
|
sl@0
|
1283 |
|
sl@0
|
1284 |
// set up the correct DFC queue
|
sl@0
|
1285 |
SetDfcQ(iController->DfcQ(0)); // sets the channel's dfc queue
|
sl@0
|
1286 |
iCompleteAllCallbackInfo.SetDfcQ(iDfcQ);
|
sl@0
|
1287 |
iStatusCallbackInfo.SetDfcQ(iDfcQ); // use the channel's dfcq for this dfc
|
sl@0
|
1288 |
iEndpointStatusCallbackInfo.SetDfcQ(iDfcQ); // use the channel's dfcq for this dfc
|
sl@0
|
1289 |
iOtgFeatureCallbackInfo.SetDfcQ(iDfcQ);
|
sl@0
|
1290 |
iMsgQ.Receive(); //start up the message q
|
sl@0
|
1291 |
TInt r = iController->RegisterClientCallback(iCompleteAllCallbackInfo);
|
sl@0
|
1292 |
if (r != KErrNone)
|
sl@0
|
1293 |
return r;
|
sl@0
|
1294 |
r = iController->RegisterForStatusChange(iStatusCallbackInfo);
|
sl@0
|
1295 |
if (r != KErrNone)
|
sl@0
|
1296 |
return r;
|
sl@0
|
1297 |
r = iController->RegisterForEndpointStatusChange(iEndpointStatusCallbackInfo);
|
sl@0
|
1298 |
if (r != KErrNone)
|
sl@0
|
1299 |
return r;
|
sl@0
|
1300 |
r = iController->RegisterForOtgFeatureChange(iOtgFeatureCallbackInfo);
|
sl@0
|
1301 |
if (r != KErrNone)
|
sl@0
|
1302 |
return r;
|
sl@0
|
1303 |
|
sl@0
|
1304 |
return r;
|
sl@0
|
1305 |
}
|
sl@0
|
1306 |
// end DoCreate.
|
sl@0
|
1307 |
|
sl@0
|
1308 |
|
sl@0
|
1309 |
//
|
sl@0
|
1310 |
// HandleMsg
|
sl@0
|
1311 |
//
|
sl@0
|
1312 |
// Events from userside arrive here, and delegated to either DoRequest, DoControl or DoCancel.
|
sl@0
|
1313 |
//
|
sl@0
|
1314 |
|
sl@0
|
1315 |
void DLddUsbcScChannel::HandleMsg(TMessageBase* aMsg)
|
sl@0
|
1316 |
{
|
sl@0
|
1317 |
TThreadMessage& m = *(TThreadMessage*)aMsg;
|
sl@0
|
1318 |
TInt id = m.iValue;
|
sl@0
|
1319 |
__KTRACE_OPT(KUSB, Kern::Printf("HandleMsg 0x%x", id));
|
sl@0
|
1320 |
|
sl@0
|
1321 |
if (id == (TInt) ECloseMsg)
|
sl@0
|
1322 |
{
|
sl@0
|
1323 |
iChannelClosing = ETrue;
|
sl@0
|
1324 |
m.Complete(KErrNone, EFalse);
|
sl@0
|
1325 |
return;
|
sl@0
|
1326 |
}
|
sl@0
|
1327 |
|
sl@0
|
1328 |
TInt r;
|
sl@0
|
1329 |
if (id < 0)
|
sl@0
|
1330 |
{
|
sl@0
|
1331 |
// DoRequest
|
sl@0
|
1332 |
TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
|
sl@0
|
1333 |
r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
|
sl@0
|
1334 |
m.Complete(r, ETrue);
|
sl@0
|
1335 |
}
|
sl@0
|
1336 |
else if (id & RDevUsbcScClient::ERequestCancel)
|
sl@0
|
1337 |
{
|
sl@0
|
1338 |
// DoCancel
|
sl@0
|
1339 |
r = DoCancel(id, (TUint) m.Ptr0(), (TUint) m.Ptr1());
|
sl@0
|
1340 |
m.Complete(r, ETrue);
|
sl@0
|
1341 |
}
|
sl@0
|
1342 |
else
|
sl@0
|
1343 |
{
|
sl@0
|
1344 |
// DoControl
|
sl@0
|
1345 |
r = DoControl(id, m.Ptr0(), m.Ptr1());
|
sl@0
|
1346 |
m.Complete(r, ETrue);
|
sl@0
|
1347 |
}
|
sl@0
|
1348 |
}
|
sl@0
|
1349 |
// end HandleMsg.
|
sl@0
|
1350 |
|
sl@0
|
1351 |
|
sl@0
|
1352 |
#define BREAK_IF_NULL_ARG(a,r) if (a==NULL) { r = KErrArgument; __KTRACE_OPT(KUSB,Kern::Printf("NULL Argument")); break; }
|
sl@0
|
1353 |
|
sl@0
|
1354 |
//
|
sl@0
|
1355 |
// DoRequest - Asynchronous requests
|
sl@0
|
1356 |
//
|
sl@0
|
1357 |
// Overrides pure virtual, called by HandleMsg. (Above)
|
sl@0
|
1358 |
//
|
sl@0
|
1359 |
TInt DLddUsbcScChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
|
sl@0
|
1360 |
{
|
sl@0
|
1361 |
TInt reqNo = aReqNo & RDevUsbcScClient::KFieldIdMask;
|
sl@0
|
1362 |
TInt r = KErrNone; // return via request notify
|
sl@0
|
1363 |
TBool needsCompletion =EFalse;
|
sl@0
|
1364 |
|
sl@0
|
1365 |
__KTRACE_OPT(KUSB, Kern::Printf("DoRequest 0x%08x", aReqNo));
|
sl@0
|
1366 |
|
sl@0
|
1367 |
if ((reqNo>RDevUsbcScClient::ERequestReadDataNotify) &&
|
sl@0
|
1368 |
(reqNo<RDevUsbcScClient::ERequestMaxRequests))
|
sl@0
|
1369 |
{
|
sl@0
|
1370 |
if (iRequestStatus[reqNo])
|
sl@0
|
1371 |
{
|
sl@0
|
1372 |
PanicClientThread(ERequestAlreadyPending);
|
sl@0
|
1373 |
return 0;
|
sl@0
|
1374 |
}
|
sl@0
|
1375 |
iRequestStatus[reqNo] = aStatus;
|
sl@0
|
1376 |
}
|
sl@0
|
1377 |
|
sl@0
|
1378 |
switch (reqNo)
|
sl@0
|
1379 |
{
|
sl@0
|
1380 |
case RDevUsbcScClient::ERequestWriteData:
|
sl@0
|
1381 |
{
|
sl@0
|
1382 |
TInt buffer = (aReqNo>>RDevUsbcScClient::KFieldBuffPos)&RDevUsbcScClient::KFieldBuffMask;
|
sl@0
|
1383 |
__KTRACE_OPT(KUSB, Kern::Printf("ERequestWriteData"));
|
sl@0
|
1384 |
BREAK_IF_NULL_ARG(a2,r);
|
sl@0
|
1385 |
|
sl@0
|
1386 |
r = DoWriteData( aStatus, buffer, (TInt) a1 /*Start*/, (TInt) a2 /* Length */,
|
sl@0
|
1387 |
aReqNo>>RDevUsbcScClient::KFieldFlagsPos ); // Flags
|
sl@0
|
1388 |
break;
|
sl@0
|
1389 |
}
|
sl@0
|
1390 |
case RDevUsbcScClient::ERequestReadDataNotify:
|
sl@0
|
1391 |
{
|
sl@0
|
1392 |
__KTRACE_OPT(KUSB, Kern::Printf("ERequestReadDataNotify"));
|
sl@0
|
1393 |
return DoReadDataNotify(aStatus, (TInt) a1, (TInt) a2); // a1 = aBufferNumber, a2 - aLength;
|
sl@0
|
1394 |
}
|
sl@0
|
1395 |
|
sl@0
|
1396 |
case RDevUsbcScClient::ERequestAlternateDeviceStatusNotify:
|
sl@0
|
1397 |
{
|
sl@0
|
1398 |
__KTRACE_OPT(KUSB, Kern::Printf("ERequestAlternateDeviceStatusNotify"));
|
sl@0
|
1399 |
BREAK_IF_NULL_ARG(a1,r);
|
sl@0
|
1400 |
iDeviceStatusNeeded = ETrue;
|
sl@0
|
1401 |
iStatusChangePtr = a1;
|
sl@0
|
1402 |
needsCompletion = AlternateDeviceStateTestComplete();
|
sl@0
|
1403 |
break;
|
sl@0
|
1404 |
}
|
sl@0
|
1405 |
case RDevUsbcScClient::ERequestReEnumerate:
|
sl@0
|
1406 |
{
|
sl@0
|
1407 |
__KTRACE_OPT(KUSB, Kern::Printf("ERequestReEnumerate"));
|
sl@0
|
1408 |
// If successful, this will complete via the status notification.
|
sl@0
|
1409 |
r = iController->ReEnumerate();
|
sl@0
|
1410 |
break;
|
sl@0
|
1411 |
}
|
sl@0
|
1412 |
case RDevUsbcScClient::ERequestEndpointStatusNotify:
|
sl@0
|
1413 |
{
|
sl@0
|
1414 |
__KTRACE_OPT(KUSB, Kern::Printf("ERequestEndpointStatusNotify"));
|
sl@0
|
1415 |
BREAK_IF_NULL_ARG(a1,r);
|
sl@0
|
1416 |
|
sl@0
|
1417 |
iEndpointStatusChangePtr = a1;
|
sl@0
|
1418 |
break;
|
sl@0
|
1419 |
}
|
sl@0
|
1420 |
case RDevUsbcScClient::ERequestOtgFeaturesNotify:
|
sl@0
|
1421 |
{
|
sl@0
|
1422 |
__KTRACE_OPT(KUSB, Kern::Printf("ERequestOtgFeaturesNotify"));
|
sl@0
|
1423 |
BREAK_IF_NULL_ARG(a1,r);
|
sl@0
|
1424 |
|
sl@0
|
1425 |
iOtgFeatureChangePtr = a1;
|
sl@0
|
1426 |
break;
|
sl@0
|
1427 |
}
|
sl@0
|
1428 |
default:
|
sl@0
|
1429 |
r = KErrNotSupported;
|
sl@0
|
1430 |
}
|
sl@0
|
1431 |
|
sl@0
|
1432 |
if ((needsCompletion) || (r != KErrNone))
|
sl@0
|
1433 |
{
|
sl@0
|
1434 |
iRequestStatus[reqNo] = aStatus;
|
sl@0
|
1435 |
Kern::RequestComplete(iClient, iRequestStatus[reqNo], r);
|
sl@0
|
1436 |
}
|
sl@0
|
1437 |
return KErrNone;
|
sl@0
|
1438 |
}
|
sl@0
|
1439 |
// end DoRequest.
|
sl@0
|
1440 |
|
sl@0
|
1441 |
|
sl@0
|
1442 |
//
|
sl@0
|
1443 |
// DoReadDataNotify
|
sl@0
|
1444 |
//
|
sl@0
|
1445 |
// This method sets up the request to facilitate the userside being notifed when new data has been read.
|
sl@0
|
1446 |
//
|
sl@0
|
1447 |
TInt DLddUsbcScChannel::DoReadDataNotify(TRequestStatus* aStatus, TInt aBufferNum, TInt aLength)
|
sl@0
|
1448 |
{
|
sl@0
|
1449 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoReadDataNotify(x, %d, 0x%x)", aBufferNum, aLength));
|
sl@0
|
1450 |
TInt r = KErrNone;
|
sl@0
|
1451 |
// check range
|
sl@0
|
1452 |
if ((aBufferNum<0) || (aBufferNum>=iNumBuffers)) // Indirectly checks that we are set up.
|
sl@0
|
1453 |
{
|
sl@0
|
1454 |
if (aBufferNum!=KUsbcScEndpointZero)
|
sl@0
|
1455 |
{
|
sl@0
|
1456 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoReadDataNotify : Bad Buffer Number!"));
|
sl@0
|
1457 |
return KErrArgument;
|
sl@0
|
1458 |
}
|
sl@0
|
1459 |
else
|
sl@0
|
1460 |
{
|
sl@0
|
1461 |
aBufferNum = iEP0OutBuff;
|
sl@0
|
1462 |
}
|
sl@0
|
1463 |
}
|
sl@0
|
1464 |
else
|
sl@0
|
1465 |
{
|
sl@0
|
1466 |
// check direction
|
sl@0
|
1467 |
if (iBuffers[aBufferNum].iDirection!=KUsbcScOut)
|
sl@0
|
1468 |
{
|
sl@0
|
1469 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoReadDataNotify : Bad Buffer Direction!"));
|
sl@0
|
1470 |
return KErrNotSupported;
|
sl@0
|
1471 |
}
|
sl@0
|
1472 |
if (!Configured())
|
sl@0
|
1473 |
return KErrUsbInterfaceNotReady;
|
sl@0
|
1474 |
}
|
sl@0
|
1475 |
SUsbcScBufferHeader* scBuffer = (SUsbcScBufferHeader*) iBuffers[aBufferNum].iBufferStart;
|
sl@0
|
1476 |
|
sl@0
|
1477 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoReadDataNotify head %x tail %x", iBuffers[aBufferNum].iHead , scBuffer->iTail ));
|
sl@0
|
1478 |
|
sl@0
|
1479 |
if (iBuffers[aBufferNum].iHead != scBuffer->iBilTail)
|
sl@0
|
1480 |
r = KErrCompletion;
|
sl@0
|
1481 |
else
|
sl@0
|
1482 |
if (iBuffers[aBufferNum].iStalled)
|
sl@0
|
1483 |
{
|
sl@0
|
1484 |
iBuffers[aBufferNum].PopStall();
|
sl@0
|
1485 |
return KErrCompletion;
|
sl@0
|
1486 |
}
|
sl@0
|
1487 |
else
|
sl@0
|
1488 |
r = iBuffers[aBufferNum].iStatusList.Add(aStatus, aLength, 0,0);
|
sl@0
|
1489 |
|
sl@0
|
1490 |
if (iBuffers[aBufferNum].iStatusList.iState==ENotRunning)
|
sl@0
|
1491 |
{
|
sl@0
|
1492 |
iBuffers[aBufferNum].StartDataRead();
|
sl@0
|
1493 |
}
|
sl@0
|
1494 |
else
|
sl@0
|
1495 |
{
|
sl@0
|
1496 |
__KTRACE_OPT(KUSB, Kern::Printf("Job in Progress!"));
|
sl@0
|
1497 |
}
|
sl@0
|
1498 |
return r;
|
sl@0
|
1499 |
}
|
sl@0
|
1500 |
// end DoReadDataNotify.
|
sl@0
|
1501 |
|
sl@0
|
1502 |
|
sl@0
|
1503 |
|
sl@0
|
1504 |
//
|
sl@0
|
1505 |
// DoWriteData
|
sl@0
|
1506 |
//
|
sl@0
|
1507 |
// This method sets up the request to write data to USB from userside.
|
sl@0
|
1508 |
//
|
sl@0
|
1509 |
TInt DLddUsbcScChannel::DoWriteData(TRequestStatus* aStatus,TInt aBufferNum, TUint aStart, TUint aLength, TUint aFlags)
|
sl@0
|
1510 |
{
|
sl@0
|
1511 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoWriteData(%d, 0x%x, 0x%x, 0x%x)", aBufferNum, aStart, aLength, aFlags));
|
sl@0
|
1512 |
if (!iUserKnowsAltSetting)
|
sl@0
|
1513 |
return KErrEof;
|
sl@0
|
1514 |
// Check Buffer Number
|
sl@0
|
1515 |
if ((aBufferNum<0) || (aBufferNum>=iNumBuffers))
|
sl@0
|
1516 |
{
|
sl@0
|
1517 |
if ((TUint)aBufferNum!=RDevUsbcScClient::KFieldBuffMask) // KUsbcScEndpointZero & KFieldBuffMas = KFieldBuffMas;
|
sl@0
|
1518 |
{
|
sl@0
|
1519 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoWriteData : Bad Buffer Number!"));
|
sl@0
|
1520 |
return KErrArgument;
|
sl@0
|
1521 |
}
|
sl@0
|
1522 |
else
|
sl@0
|
1523 |
{
|
sl@0
|
1524 |
aBufferNum = iEP0InBuff;
|
sl@0
|
1525 |
}
|
sl@0
|
1526 |
}
|
sl@0
|
1527 |
else
|
sl@0
|
1528 |
{
|
sl@0
|
1529 |
// check direction
|
sl@0
|
1530 |
if (iBuffers[aBufferNum].iDirection!=KUsbcScIn)
|
sl@0
|
1531 |
{
|
sl@0
|
1532 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoWriteData Bad endpoint Direction"));
|
sl@0
|
1533 |
return KErrArgument;
|
sl@0
|
1534 |
}
|
sl@0
|
1535 |
}
|
sl@0
|
1536 |
|
sl@0
|
1537 |
TUsbcScBuffer& buf=iBuffers[aBufferNum];
|
sl@0
|
1538 |
|
sl@0
|
1539 |
if ((aStart< (((TLinAddr) buf.iBufferStart)-buf.iChunkAddr)) || ((aStart+aLength)>iBuffers[aBufferNum].iBufferEnd))
|
sl@0
|
1540 |
{
|
sl@0
|
1541 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DoWriteData Bad Range aStart or aLength 0x%x > 0x%x + 0x%x < 0x%x", (((TLinAddr) buf.iBufferStart)-buf.iChunkAddr),aStart, aLength, iBuffers[aBufferNum].iBufferEnd ));
|
sl@0
|
1542 |
return KErrArgument;
|
sl@0
|
1543 |
}
|
sl@0
|
1544 |
|
sl@0
|
1545 |
if ( (aBufferNum != iEP0InBuff) && !Configured())
|
sl@0
|
1546 |
return KErrUsbInterfaceNotReady;
|
sl@0
|
1547 |
|
sl@0
|
1548 |
if (aStart & ~buf.iAlignMask)
|
sl@0
|
1549 |
{
|
sl@0
|
1550 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScBuffer::DoDataWrite: address 0x%x unaligned.",aStart));
|
sl@0
|
1551 |
return KErrArgument;
|
sl@0
|
1552 |
}
|
sl@0
|
1553 |
|
sl@0
|
1554 |
TInt r = iBuffers[aBufferNum].iStatusList.Add(aStatus, aLength, aStart, aFlags); //update
|
sl@0
|
1555 |
|
sl@0
|
1556 |
if (iBuffers[aBufferNum].iStatusList.iState==ENotRunning)
|
sl@0
|
1557 |
{
|
sl@0
|
1558 |
iBuffers[aBufferNum].StartDataWrite();
|
sl@0
|
1559 |
}
|
sl@0
|
1560 |
else
|
sl@0
|
1561 |
{
|
sl@0
|
1562 |
__KTRACE_OPT(KUSB, Kern::Printf("Job in Progress!"));
|
sl@0
|
1563 |
}
|
sl@0
|
1564 |
|
sl@0
|
1565 |
|
sl@0
|
1566 |
return r;
|
sl@0
|
1567 |
}
|
sl@0
|
1568 |
// end DoWriteData.
|
sl@0
|
1569 |
|
sl@0
|
1570 |
|
sl@0
|
1571 |
//
|
sl@0
|
1572 |
// Cancel an outstanding request // Cancel need reworking.
|
sl@0
|
1573 |
//
|
sl@0
|
1574 |
TInt DLddUsbcScChannel::DoCancel(TInt aReqNo, TUint aBuff, TUint aSpair)
|
sl@0
|
1575 |
{
|
sl@0
|
1576 |
TInt r = KErrNone;
|
sl@0
|
1577 |
TInt direction=KUsbcScOut;
|
sl@0
|
1578 |
|
sl@0
|
1579 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel: 0x%x aBuff 0x%x", aReqNo, aBuff));
|
sl@0
|
1580 |
switch (aReqNo)
|
sl@0
|
1581 |
{
|
sl@0
|
1582 |
case RDevUsbcScClient::ERequestCancel:
|
sl@0
|
1583 |
TInt buffer;
|
sl@0
|
1584 |
TInt mask;
|
sl@0
|
1585 |
|
sl@0
|
1586 |
for (buffer=1, mask=1; buffer<iNumBuffers; buffer++,mask<<=1)
|
sl@0
|
1587 |
if (aBuff&mask)
|
sl@0
|
1588 |
iBuffers[buffer].Cancel(KErrCancel);
|
sl@0
|
1589 |
|
sl@0
|
1590 |
return KErrNone;
|
sl@0
|
1591 |
|
sl@0
|
1592 |
// coverity[missing_break]
|
sl@0
|
1593 |
case RDevUsbcScClient::ERequestWriteDataCancel:
|
sl@0
|
1594 |
direction = KUsbcScIn;
|
sl@0
|
1595 |
case RDevUsbcScClient::ERequestReadDataNotifyCancel:
|
sl@0
|
1596 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel Direction %d endpoints: 0x%x",direction, aReqNo));
|
sl@0
|
1597 |
|
sl@0
|
1598 |
if (((TInt)aBuff)==KUsbcScEndpointZero) // EP0 is bi-directional, so pick correct buffer for call type
|
sl@0
|
1599 |
{
|
sl@0
|
1600 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel Cancel Endpoint 0/%d",direction));
|
sl@0
|
1601 |
iEp0Endpoint->AbortTransfer();
|
sl@0
|
1602 |
if (direction==KUsbcScIn)
|
sl@0
|
1603 |
aBuff=iEP0InBuff;
|
sl@0
|
1604 |
else
|
sl@0
|
1605 |
aBuff=iEP0OutBuff;
|
sl@0
|
1606 |
}
|
sl@0
|
1607 |
else if ((TInt)aBuff >= iNumBuffers) // check buff no range.
|
sl@0
|
1608 |
{
|
sl@0
|
1609 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel Error: Bad buffer number"));
|
sl@0
|
1610 |
return KErrArgument;
|
sl@0
|
1611 |
}
|
sl@0
|
1612 |
|
sl@0
|
1613 |
if ((iBuffers[aBuff].iDirection&1)!=direction) // Does direction match call type?
|
sl@0
|
1614 |
{
|
sl@0
|
1615 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel Error: Bad buffer direction"));
|
sl@0
|
1616 |
return KErrArgument;
|
sl@0
|
1617 |
}
|
sl@0
|
1618 |
iBuffers[aBuff].iStatusList.CancelQueued();
|
sl@0
|
1619 |
iBuffers[aBuff].Cancel(KErrCancel);
|
sl@0
|
1620 |
|
sl@0
|
1621 |
return KErrNone;
|
sl@0
|
1622 |
|
sl@0
|
1623 |
case RDevUsbcScClient::ERequestAlternateDeviceStatusNotifyCancel:
|
sl@0
|
1624 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel: ERequestAlternateDeviceStatusNotify 0x%x", aReqNo));
|
sl@0
|
1625 |
iDeviceStatusNeeded = EFalse;
|
sl@0
|
1626 |
iStatusFifo->FlushQueue();
|
sl@0
|
1627 |
if (iStatusChangePtr)
|
sl@0
|
1628 |
{
|
sl@0
|
1629 |
TInt deviceState = iController->GetDeviceStatus();
|
sl@0
|
1630 |
r = Kern::ThreadRawWrite(iClient, iStatusChangePtr, &deviceState, sizeof(deviceState), iClient);
|
sl@0
|
1631 |
if (r != KErrNone)
|
sl@0
|
1632 |
PanicClientThread(r);
|
sl@0
|
1633 |
iStatusChangePtr = NULL;
|
sl@0
|
1634 |
}
|
sl@0
|
1635 |
break;
|
sl@0
|
1636 |
|
sl@0
|
1637 |
case RDevUsbcScClient::ERequestReEnumerateCancel:
|
sl@0
|
1638 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestReEnumerate: 0x%x", aReqNo));
|
sl@0
|
1639 |
break;
|
sl@0
|
1640 |
|
sl@0
|
1641 |
case RDevUsbcScClient::ERequestEndpointStatusNotifyCancel:
|
sl@0
|
1642 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestEndpointStatusNotify: 0x%x", aReqNo));
|
sl@0
|
1643 |
CancelNotifyEndpointStatus();
|
sl@0
|
1644 |
break;
|
sl@0
|
1645 |
|
sl@0
|
1646 |
case RDevUsbcScClient::ERequestOtgFeaturesNotifyCancel:
|
sl@0
|
1647 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestOtgFeaturesNotify: 0x%x", aReqNo));
|
sl@0
|
1648 |
CancelNotifyOtgFeatures();
|
sl@0
|
1649 |
break;
|
sl@0
|
1650 |
|
sl@0
|
1651 |
default:
|
sl@0
|
1652 |
__KTRACE_OPT(KUSB, Kern::Printf("DoCancel Unknown! 0x%x", aReqNo));
|
sl@0
|
1653 |
return KErrArgument;
|
sl@0
|
1654 |
}
|
sl@0
|
1655 |
|
sl@0
|
1656 |
Kern::RequestComplete(iClient,iRequestStatus[aReqNo & ~RDevUsbcScClient::ERequestCancel], KErrCancel);
|
sl@0
|
1657 |
return r;
|
sl@0
|
1658 |
}
|
sl@0
|
1659 |
|
sl@0
|
1660 |
|
sl@0
|
1661 |
void DLddUsbcScChannel::CancelNotifyEndpointStatus()
|
sl@0
|
1662 |
{
|
sl@0
|
1663 |
if (iEndpointStatusChangePtr)
|
sl@0
|
1664 |
{
|
sl@0
|
1665 |
TUint epBitmap = 0;
|
sl@0
|
1666 |
for (TInt i = 1; i <= iNumberOfEndpoints; i++)
|
sl@0
|
1667 |
{
|
sl@0
|
1668 |
TInt v = iController->GetEndpointStatus(this, iEndpoint[i]->RealEpNumber());
|
sl@0
|
1669 |
TUint b;
|
sl@0
|
1670 |
(v == EEndpointStateStalled) ? b = 1 : b = 0;
|
sl@0
|
1671 |
epBitmap |= b << i;
|
sl@0
|
1672 |
}
|
sl@0
|
1673 |
TInt r=Kern::ThreadRawWrite(iClient, iEndpointStatusChangePtr, (TUint8*) &epBitmap, sizeof(epBitmap), iClient);
|
sl@0
|
1674 |
if (r != KErrNone)
|
sl@0
|
1675 |
PanicClientThread(r);
|
sl@0
|
1676 |
iEndpointStatusChangePtr = NULL;
|
sl@0
|
1677 |
}
|
sl@0
|
1678 |
}
|
sl@0
|
1679 |
|
sl@0
|
1680 |
void DLddUsbcScChannel::CancelNotifyOtgFeatures()
|
sl@0
|
1681 |
{
|
sl@0
|
1682 |
if (iOtgFeatureChangePtr)
|
sl@0
|
1683 |
{
|
sl@0
|
1684 |
TUint8 features;
|
sl@0
|
1685 |
iController->GetCurrentOtgFeatures(features);
|
sl@0
|
1686 |
TInt r=Kern::ThreadRawWrite(iClient, iOtgFeatureChangePtr, (TUint8*)&features, sizeof(features), iClient);
|
sl@0
|
1687 |
if (r != KErrNone)
|
sl@0
|
1688 |
PanicClientThread(r);
|
sl@0
|
1689 |
iOtgFeatureChangePtr = NULL;
|
sl@0
|
1690 |
}
|
sl@0
|
1691 |
}
|
sl@0
|
1692 |
|
sl@0
|
1693 |
|
sl@0
|
1694 |
|
sl@0
|
1695 |
//
|
sl@0
|
1696 |
// DoControl - Synchronous requests
|
sl@0
|
1697 |
//
|
sl@0
|
1698 |
// Called from HandleMsg.
|
sl@0
|
1699 |
|
sl@0
|
1700 |
TInt DLddUsbcScChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
|
sl@0
|
1701 |
{
|
sl@0
|
1702 |
__KTRACE_OPT(KUSB, Kern::Printf("DoControl: %d", aFunction));
|
sl@0
|
1703 |
|
sl@0
|
1704 |
TInt r = KErrNone;
|
sl@0
|
1705 |
TInt ep, param;
|
sl@0
|
1706 |
TUsbcScEndpoint* pEndpoint;
|
sl@0
|
1707 |
TPtrC8 pZeroDesc(NULL, 0);
|
sl@0
|
1708 |
TEndpointDescriptorInfo epInfo;
|
sl@0
|
1709 |
TUsbcScIfcInfo ifcInfo;
|
sl@0
|
1710 |
TCSDescriptorInfo desInfo;
|
sl@0
|
1711 |
TUsbcEndpointResource epRes;
|
sl@0
|
1712 |
|
sl@0
|
1713 |
switch (aFunction)
|
sl@0
|
1714 |
{
|
sl@0
|
1715 |
case RDevUsbcScClient::EControlEndpointZeroRequestError:
|
sl@0
|
1716 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroRequestError"));
|
sl@0
|
1717 |
r = KErrNone;
|
sl@0
|
1718 |
if (iOwnsDeviceControl || (iValidInterface && iDeviceState == EUsbcDeviceStateConfigured))
|
sl@0
|
1719 |
{
|
sl@0
|
1720 |
iController->Ep0Stall(this);
|
sl@0
|
1721 |
}
|
sl@0
|
1722 |
else
|
sl@0
|
1723 |
{
|
sl@0
|
1724 |
if (iDeviceState != EUsbcDeviceStateConfigured)
|
sl@0
|
1725 |
r = KErrUsbDeviceNotConfigured;
|
sl@0
|
1726 |
else
|
sl@0
|
1727 |
r = KErrUsbInterfaceNotReady;
|
sl@0
|
1728 |
}
|
sl@0
|
1729 |
break;
|
sl@0
|
1730 |
|
sl@0
|
1731 |
case RDevUsbcScClient::EControlGetAlternateSetting:
|
sl@0
|
1732 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetAlternateSetting"));
|
sl@0
|
1733 |
if (iValidInterface && iDeviceState == EUsbcDeviceStateConfigured)
|
sl@0
|
1734 |
{
|
sl@0
|
1735 |
r = iController->GetInterfaceNumber(this, param);
|
sl@0
|
1736 |
if (r == KErrNone)
|
sl@0
|
1737 |
{
|
sl@0
|
1738 |
r = Kern::ThreadRawWrite(iClient, a1, ¶m, sizeof(param), iClient);
|
sl@0
|
1739 |
if (r != KErrNone)
|
sl@0
|
1740 |
PanicClientThread(r);
|
sl@0
|
1741 |
}
|
sl@0
|
1742 |
}
|
sl@0
|
1743 |
else
|
sl@0
|
1744 |
{
|
sl@0
|
1745 |
if (iDeviceState != EUsbcDeviceStateConfigured)
|
sl@0
|
1746 |
r = KErrUsbDeviceNotConfigured;
|
sl@0
|
1747 |
else
|
sl@0
|
1748 |
r = KErrUsbInterfaceNotReady;
|
sl@0
|
1749 |
}
|
sl@0
|
1750 |
break;
|
sl@0
|
1751 |
|
sl@0
|
1752 |
case RDevUsbcScClient::EControlDeviceStatus:
|
sl@0
|
1753 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceStatus"));
|
sl@0
|
1754 |
param = iController->GetDeviceStatus();
|
sl@0
|
1755 |
r = Kern::ThreadRawWrite(iClient, a1, ¶m, sizeof(param), iClient);
|
sl@0
|
1756 |
if (r != KErrNone)
|
sl@0
|
1757 |
PanicClientThread(r);
|
sl@0
|
1758 |
break;
|
sl@0
|
1759 |
|
sl@0
|
1760 |
case RDevUsbcScClient::EControlEndpointStatus:
|
sl@0
|
1761 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointStatus"));
|
sl@0
|
1762 |
if (iValidInterface && ValidEndpoint((TInt) a1))
|
sl@0
|
1763 |
{
|
sl@0
|
1764 |
pEndpoint = iEndpoint[(TInt)a1];
|
sl@0
|
1765 |
if (pEndpoint == NULL)
|
sl@0
|
1766 |
r = KErrNotSupported;
|
sl@0
|
1767 |
else
|
sl@0
|
1768 |
{
|
sl@0
|
1769 |
param = iController->GetEndpointStatus(this, iEndpoint[(TInt)a1]->RealEpNumber());
|
sl@0
|
1770 |
r = Kern::ThreadRawWrite(iClient, a2, ¶m, sizeof(param), iClient);
|
sl@0
|
1771 |
if (r != KErrNone)
|
sl@0
|
1772 |
PanicClientThread(r);
|
sl@0
|
1773 |
}
|
sl@0
|
1774 |
}
|
sl@0
|
1775 |
else
|
sl@0
|
1776 |
{
|
sl@0
|
1777 |
if (iDeviceState != EUsbcDeviceStateConfigured)
|
sl@0
|
1778 |
r = KErrUsbDeviceNotConfigured;
|
sl@0
|
1779 |
else
|
sl@0
|
1780 |
r = KErrUsbInterfaceNotReady;
|
sl@0
|
1781 |
}
|
sl@0
|
1782 |
break;
|
sl@0
|
1783 |
|
sl@0
|
1784 |
case RDevUsbcScClient::EControlEndpointCaps:
|
sl@0
|
1785 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointCaps"));
|
sl@0
|
1786 |
r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
|
sl@0
|
1787 |
if (r != KErrNone)
|
sl@0
|
1788 |
PanicClientThread(r);
|
sl@0
|
1789 |
iController->EndpointCaps(this, *((TDes8*) a1));
|
sl@0
|
1790 |
break;
|
sl@0
|
1791 |
|
sl@0
|
1792 |
case RDevUsbcScClient::EControlDeviceCaps:
|
sl@0
|
1793 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceCaps"));
|
sl@0
|
1794 |
r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
|
sl@0
|
1795 |
if (r != KErrNone)
|
sl@0
|
1796 |
PanicClientThread(r);
|
sl@0
|
1797 |
iController->DeviceCaps(this, *((TDes8*) a1));
|
sl@0
|
1798 |
break;
|
sl@0
|
1799 |
|
sl@0
|
1800 |
case RDevUsbcScClient::EControlSendEp0StatusPacket:
|
sl@0
|
1801 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSendEp0StatusPacket"));
|
sl@0
|
1802 |
iController->SendEp0StatusPacket(this);
|
sl@0
|
1803 |
break;
|
sl@0
|
1804 |
|
sl@0
|
1805 |
case RDevUsbcScClient::EControlHaltEndpoint:
|
sl@0
|
1806 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlHaltEndpoint"));
|
sl@0
|
1807 |
if (iValidInterface && ValidEndpoint((TInt) a1))
|
sl@0
|
1808 |
{
|
sl@0
|
1809 |
r = iController->HaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
|
sl@0
|
1810 |
}
|
sl@0
|
1811 |
else
|
sl@0
|
1812 |
{
|
sl@0
|
1813 |
if (iDeviceState != EUsbcDeviceStateConfigured)
|
sl@0
|
1814 |
r = KErrUsbDeviceNotConfigured;
|
sl@0
|
1815 |
else
|
sl@0
|
1816 |
r = KErrUsbInterfaceNotReady;
|
sl@0
|
1817 |
}
|
sl@0
|
1818 |
break;
|
sl@0
|
1819 |
|
sl@0
|
1820 |
case RDevUsbcScClient::EControlClearHaltEndpoint:
|
sl@0
|
1821 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlClearHaltEndpoint"));
|
sl@0
|
1822 |
if (iValidInterface && ValidEndpoint((TInt) a1))
|
sl@0
|
1823 |
{
|
sl@0
|
1824 |
r = iController->ClearHaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
|
sl@0
|
1825 |
}
|
sl@0
|
1826 |
else
|
sl@0
|
1827 |
{
|
sl@0
|
1828 |
if (iDeviceState != EUsbcDeviceStateConfigured)
|
sl@0
|
1829 |
r = KErrUsbDeviceNotConfigured;
|
sl@0
|
1830 |
else
|
sl@0
|
1831 |
r = KErrUsbInterfaceNotReady;
|
sl@0
|
1832 |
}
|
sl@0
|
1833 |
break;
|
sl@0
|
1834 |
|
sl@0
|
1835 |
case RDevUsbcScClient::EControlDumpRegisters:
|
sl@0
|
1836 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlDumpRegisters"));
|
sl@0
|
1837 |
iController->DumpRegisters();
|
sl@0
|
1838 |
break;
|
sl@0
|
1839 |
|
sl@0
|
1840 |
case RDevUsbcScClient::EControlReleaseDeviceControl:
|
sl@0
|
1841 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseDeviceControl"));
|
sl@0
|
1842 |
iController->ReleaseDeviceControl(this);
|
sl@0
|
1843 |
iOwnsDeviceControl = EFalse;
|
sl@0
|
1844 |
break;
|
sl@0
|
1845 |
|
sl@0
|
1846 |
case RDevUsbcScClient::EControlEndpointZeroMaxPacketSizes:
|
sl@0
|
1847 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroMaxPacketSizes"));
|
sl@0
|
1848 |
r = iController->EndpointZeroMaxPacketSizes();
|
sl@0
|
1849 |
break;
|
sl@0
|
1850 |
|
sl@0
|
1851 |
case RDevUsbcScClient::EControlSetEndpointZeroMaxPacketSize:
|
sl@0
|
1852 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointZeroMaxPacketSize"));
|
sl@0
|
1853 |
r = iController->SetEndpointZeroMaxPacketSize(reinterpret_cast<TInt>(a1));
|
sl@0
|
1854 |
break;
|
sl@0
|
1855 |
|
sl@0
|
1856 |
case RDevUsbcScClient::EControlGetEndpointZeroMaxPacketSize:
|
sl@0
|
1857 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointZeroMaxPacketSize"));
|
sl@0
|
1858 |
r = iController->Ep0PacketSize();
|
sl@0
|
1859 |
break;
|
sl@0
|
1860 |
|
sl@0
|
1861 |
case RDevUsbcScClient::EControlGetDeviceDescriptor:
|
sl@0
|
1862 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptor"));
|
sl@0
|
1863 |
r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
|
sl@0
|
1864 |
if (r != KErrNone)
|
sl@0
|
1865 |
PanicClientThread(r);
|
sl@0
|
1866 |
r = iController->GetDeviceDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1867 |
break;
|
sl@0
|
1868 |
|
sl@0
|
1869 |
case RDevUsbcScClient::EControlSetDeviceDescriptor:
|
sl@0
|
1870 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceDescriptor"));
|
sl@0
|
1871 |
BREAK_IF_NULL_ARG(a1,r);
|
sl@0
|
1872 |
r = iController->SetDeviceDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1873 |
break;
|
sl@0
|
1874 |
|
sl@0
|
1875 |
case RDevUsbcScClient::EControlGetDeviceDescriptorSize:
|
sl@0
|
1876 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptorSize"));
|
sl@0
|
1877 |
BREAK_IF_NULL_ARG(a1,r);
|
sl@0
|
1878 |
r = iController->GetDeviceDescriptorSize(iClient, *((TDes8*) a1));
|
sl@0
|
1879 |
break;
|
sl@0
|
1880 |
|
sl@0
|
1881 |
case RDevUsbcScClient::EControlGetConfigurationDescriptor:
|
sl@0
|
1882 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptor"));
|
sl@0
|
1883 |
r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
|
sl@0
|
1884 |
if (r != KErrNone)
|
sl@0
|
1885 |
PanicClientThread(r);
|
sl@0
|
1886 |
r = iController->GetConfigurationDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1887 |
break;
|
sl@0
|
1888 |
|
sl@0
|
1889 |
case RDevUsbcScClient::EControlGetConfigurationDescriptorSize:
|
sl@0
|
1890 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptorSize"));
|
sl@0
|
1891 |
if (a1 != NULL)
|
sl@0
|
1892 |
{
|
sl@0
|
1893 |
r = iController->GetConfigurationDescriptorSize(iClient, *((TDes8*) a1));
|
sl@0
|
1894 |
}
|
sl@0
|
1895 |
else
|
sl@0
|
1896 |
r = KErrArgument;
|
sl@0
|
1897 |
break;
|
sl@0
|
1898 |
|
sl@0
|
1899 |
case RDevUsbcScClient::EControlSetConfigurationDescriptor:
|
sl@0
|
1900 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationDescriptor"));
|
sl@0
|
1901 |
r = iController->SetConfigurationDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1902 |
break;
|
sl@0
|
1903 |
|
sl@0
|
1904 |
case RDevUsbcScClient::EControlGetInterfaceDescriptor:
|
sl@0
|
1905 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptor"));
|
sl@0
|
1906 |
r = iController->GetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
|
sl@0
|
1907 |
break;
|
sl@0
|
1908 |
|
sl@0
|
1909 |
case RDevUsbcScClient::EControlGetInterfaceDescriptorSize:
|
sl@0
|
1910 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptorSize"));
|
sl@0
|
1911 |
r = iController->GetInterfaceDescriptorSize(iClient, this, (TInt) a1, *(TDes8*) a2);
|
sl@0
|
1912 |
break;
|
sl@0
|
1913 |
|
sl@0
|
1914 |
case RDevUsbcScClient::EControlSetInterfaceDescriptor:
|
sl@0
|
1915 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterfaceDescriptor"));
|
sl@0
|
1916 |
r = iController->SetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
|
sl@0
|
1917 |
break;
|
sl@0
|
1918 |
|
sl@0
|
1919 |
case RDevUsbcScClient::EControlGetEndpointDescriptor:
|
sl@0
|
1920 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptor"));
|
sl@0
|
1921 |
r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
|
sl@0
|
1922 |
if (r != KErrNone)
|
sl@0
|
1923 |
PanicClientThread(r);
|
sl@0
|
1924 |
ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
|
sl@0
|
1925 |
r = (ep<0)?ep:iController->GetEndpointDescriptor(iClient, this, epInfo.iSetting,
|
sl@0
|
1926 |
ep, *(TDes8*) epInfo.iArg);
|
sl@0
|
1927 |
break;
|
sl@0
|
1928 |
|
sl@0
|
1929 |
case RDevUsbcScClient::EControlGetEndpointDescriptorSize:
|
sl@0
|
1930 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptorSize"));
|
sl@0
|
1931 |
r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
|
sl@0
|
1932 |
if (r != KErrNone)
|
sl@0
|
1933 |
PanicClientThread(r);
|
sl@0
|
1934 |
ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
|
sl@0
|
1935 |
r = iController->GetEndpointDescriptorSize(iClient, this, epInfo.iSetting,
|
sl@0
|
1936 |
ep, *(TDes8*) epInfo.iArg);
|
sl@0
|
1937 |
break;
|
sl@0
|
1938 |
|
sl@0
|
1939 |
case RDevUsbcScClient::EControlSetEndpointDescriptor:
|
sl@0
|
1940 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointDescriptor"));
|
sl@0
|
1941 |
r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
|
sl@0
|
1942 |
if (r != KErrNone)
|
sl@0
|
1943 |
PanicClientThread(r);
|
sl@0
|
1944 |
ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
|
sl@0
|
1945 |
r = iController->SetEndpointDescriptor(iClient, this, epInfo.iSetting,
|
sl@0
|
1946 |
ep, *(TDes8*)epInfo.iArg);
|
sl@0
|
1947 |
break;
|
sl@0
|
1948 |
|
sl@0
|
1949 |
case RDevUsbcScClient::EControlGetDeviceQualifierDescriptor:
|
sl@0
|
1950 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceQualifierDescriptor"));
|
sl@0
|
1951 |
r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
|
sl@0
|
1952 |
if (r != KErrNone)
|
sl@0
|
1953 |
PanicClientThread(r);
|
sl@0
|
1954 |
r = iController->GetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1955 |
break;
|
sl@0
|
1956 |
|
sl@0
|
1957 |
case RDevUsbcScClient::EControlSetDeviceQualifierDescriptor:
|
sl@0
|
1958 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceQualifierDescriptor"));
|
sl@0
|
1959 |
BREAK_IF_NULL_ARG(a1,r);
|
sl@0
|
1960 |
r = iController->SetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1961 |
break;
|
sl@0
|
1962 |
|
sl@0
|
1963 |
case RDevUsbcScClient::EControlGetOtherSpeedConfigurationDescriptor:
|
sl@0
|
1964 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetOtherSpeedConfigurationDescriptor"));
|
sl@0
|
1965 |
r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
|
sl@0
|
1966 |
if (r != KErrNone)
|
sl@0
|
1967 |
PanicClientThread(r);
|
sl@0
|
1968 |
r = iController->GetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1969 |
break;
|
sl@0
|
1970 |
|
sl@0
|
1971 |
case RDevUsbcScClient::EControlSetOtherSpeedConfigurationDescriptor:
|
sl@0
|
1972 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetOtherSpeedConfigurationDescriptor"));
|
sl@0
|
1973 |
r = iController->SetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
|
sl@0
|
1974 |
break;
|
sl@0
|
1975 |
|
sl@0
|
1976 |
|
sl@0
|
1977 |
case RDevUsbcScClient::EControlGetCSInterfaceDescriptor:
|
sl@0
|
1978 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptor"));
|
sl@0
|
1979 |
r = iController->GetCSInterfaceDescriptorBlock(iClient, this, (TInt) a1, *((TDes8*) a2));
|
sl@0
|
1980 |
break;
|
sl@0
|
1981 |
|
sl@0
|
1982 |
case RDevUsbcScClient::EControlGetCSInterfaceDescriptorSize:
|
sl@0
|
1983 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptorSize"));
|
sl@0
|
1984 |
r = iController->GetCSInterfaceDescriptorBlockSize(iClient, this, (TInt) a1, *(TDes8*) a2);
|
sl@0
|
1985 |
break;
|
sl@0
|
1986 |
|
sl@0
|
1987 |
case RDevUsbcScClient::EControlGetCSEndpointDescriptor:
|
sl@0
|
1988 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptor"));
|
sl@0
|
1989 |
r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
|
sl@0
|
1990 |
if (r != KErrNone)
|
sl@0
|
1991 |
PanicClientThread(r);
|
sl@0
|
1992 |
ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
|
sl@0
|
1993 |
r = iController->GetCSEndpointDescriptorBlock(iClient, this, epInfo.iSetting,
|
sl@0
|
1994 |
ep, *(TDes8*) epInfo.iArg);
|
sl@0
|
1995 |
break;
|
sl@0
|
1996 |
|
sl@0
|
1997 |
case RDevUsbcScClient::EControlGetCSEndpointDescriptorSize:
|
sl@0
|
1998 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptorSize"));
|
sl@0
|
1999 |
r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
|
sl@0
|
2000 |
if (r != KErrNone)
|
sl@0
|
2001 |
PanicClientThread(r);
|
sl@0
|
2002 |
ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
|
sl@0
|
2003 |
r = iController->GetCSEndpointDescriptorBlockSize(iClient, this, epInfo.iSetting,
|
sl@0
|
2004 |
ep, *(TDes8*) epInfo.iArg);
|
sl@0
|
2005 |
break;
|
sl@0
|
2006 |
|
sl@0
|
2007 |
case RDevUsbcScClient::EControlSignalRemoteWakeup:
|
sl@0
|
2008 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSignalRemoteWakeup"));
|
sl@0
|
2009 |
r = iController->SignalRemoteWakeup();
|
sl@0
|
2010 |
break;
|
sl@0
|
2011 |
|
sl@0
|
2012 |
case RDevUsbcScClient::EControlDeviceDisconnectFromHost:
|
sl@0
|
2013 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceDisconnectFromHost"));
|
sl@0
|
2014 |
r = iController->UsbDisconnect();
|
sl@0
|
2015 |
break;
|
sl@0
|
2016 |
|
sl@0
|
2017 |
case RDevUsbcScClient::EControlDeviceConnectToHost:
|
sl@0
|
2018 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceConnectToHost"));
|
sl@0
|
2019 |
r = iController->UsbConnect();
|
sl@0
|
2020 |
break;
|
sl@0
|
2021 |
|
sl@0
|
2022 |
case RDevUsbcScClient::EControlDevicePowerUpUdc:
|
sl@0
|
2023 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlDevicePowerUpUdc"));
|
sl@0
|
2024 |
r = iController->PowerUpUdc();
|
sl@0
|
2025 |
break;
|
sl@0
|
2026 |
|
sl@0
|
2027 |
case RDevUsbcScClient::EControlSetDeviceControl:
|
sl@0
|
2028 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl"));
|
sl@0
|
2029 |
r = iController->SetDeviceControl(this);
|
sl@0
|
2030 |
if (r == KErrNone)
|
sl@0
|
2031 |
{
|
sl@0
|
2032 |
iOwnsDeviceControl = ETrue;
|
sl@0
|
2033 |
if (iEp0Endpoint == NULL)
|
sl@0
|
2034 |
{
|
sl@0
|
2035 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl"));
|
sl@0
|
2036 |
r = SetupEp0();
|
sl@0
|
2037 |
if (r != KErrNone)
|
sl@0
|
2038 |
{
|
sl@0
|
2039 |
__KTRACE_OPT(KPANIC, Kern::Printf(" Error: SetupEp0() failed"));
|
sl@0
|
2040 |
iController->ReleaseDeviceControl(this);
|
sl@0
|
2041 |
iOwnsDeviceControl=EFalse;
|
sl@0
|
2042 |
DestroyEp0();
|
sl@0
|
2043 |
}
|
sl@0
|
2044 |
}
|
sl@0
|
2045 |
}
|
sl@0
|
2046 |
else
|
sl@0
|
2047 |
r = KErrInUse;
|
sl@0
|
2048 |
break;
|
sl@0
|
2049 |
|
sl@0
|
2050 |
case RDevUsbcScClient::EControlCurrentlyUsingHighSpeed:
|
sl@0
|
2051 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlCurrentlyUsingHighSpeed"));
|
sl@0
|
2052 |
r = iController->CurrentlyUsingHighSpeed();
|
sl@0
|
2053 |
break;
|
sl@0
|
2054 |
|
sl@0
|
2055 |
case RDevUsbcScClient::EControlSetInterface:
|
sl@0
|
2056 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterface"));
|
sl@0
|
2057 |
r = Kern::ThreadRawRead(iClient, a2, &ifcInfo, sizeof(ifcInfo));
|
sl@0
|
2058 |
if (r != KErrNone)
|
sl@0
|
2059 |
PanicClientThread(r);
|
sl@0
|
2060 |
r = SetInterface((TInt) a1, &ifcInfo);
|
sl@0
|
2061 |
break;
|
sl@0
|
2062 |
|
sl@0
|
2063 |
case RDevUsbcScClient::EControlReleaseInterface:
|
sl@0
|
2064 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseInterface"));
|
sl@0
|
2065 |
if (!iRealizeCalled)
|
sl@0
|
2066 |
{
|
sl@0
|
2067 |
r = iController->ReleaseInterface(this, (TInt) a1);
|
sl@0
|
2068 |
if (r == KErrNone)
|
sl@0
|
2069 |
{
|
sl@0
|
2070 |
DestroyInterface((TUint) a1);
|
sl@0
|
2071 |
}
|
sl@0
|
2072 |
else
|
sl@0
|
2073 |
{
|
sl@0
|
2074 |
__KTRACE_OPT(KPANIC, Kern::Printf(" Error in PIL: LDD interface won't be released."));
|
sl@0
|
2075 |
}
|
sl@0
|
2076 |
}
|
sl@0
|
2077 |
else
|
sl@0
|
2078 |
r = KErrUsbAlreadyRealized;
|
sl@0
|
2079 |
break;
|
sl@0
|
2080 |
|
sl@0
|
2081 |
case RDevUsbcScClient::EControlSetCSInterfaceDescriptor:
|
sl@0
|
2082 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSInterfaceDescriptor"));
|
sl@0
|
2083 |
r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
|
sl@0
|
2084 |
if (r != KErrNone)
|
sl@0
|
2085 |
PanicClientThread(r);
|
sl@0
|
2086 |
r = iController->SetCSInterfaceDescriptorBlock(iClient, this, desInfo.iSetting,
|
sl@0
|
2087 |
*reinterpret_cast<const TDes8*>(desInfo.iArg),
|
sl@0
|
2088 |
desInfo.iSize);
|
sl@0
|
2089 |
break;
|
sl@0
|
2090 |
|
sl@0
|
2091 |
case RDevUsbcScClient::EControlSetCSEndpointDescriptor:
|
sl@0
|
2092 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSEndpointDescriptor"));
|
sl@0
|
2093 |
r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
|
sl@0
|
2094 |
if (r != KErrNone)
|
sl@0
|
2095 |
PanicClientThread(r);
|
sl@0
|
2096 |
ep = EpFromAlternateSetting(desInfo.iSetting, desInfo.iEndpoint);
|
sl@0
|
2097 |
r = iController->SetCSEndpointDescriptorBlock(iClient, this, desInfo.iSetting, ep,
|
sl@0
|
2098 |
*reinterpret_cast<const TDes8*>(desInfo.iArg),
|
sl@0
|
2099 |
desInfo.iSize);
|
sl@0
|
2100 |
break;
|
sl@0
|
2101 |
|
sl@0
|
2102 |
case RDevUsbcScClient::EControlGetStringDescriptorLangId:
|
sl@0
|
2103 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptorLangId"));
|
sl@0
|
2104 |
r = iController->GetStringDescriptorLangId(iClient, *((TDes8*) a1));
|
sl@0
|
2105 |
break;
|
sl@0
|
2106 |
|
sl@0
|
2107 |
case RDevUsbcScClient::EControlSetStringDescriptorLangId:
|
sl@0
|
2108 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptorLangId"));
|
sl@0
|
2109 |
r = iController->SetStringDescriptorLangId(reinterpret_cast<TUint>(a1));
|
sl@0
|
2110 |
break;
|
sl@0
|
2111 |
|
sl@0
|
2112 |
case RDevUsbcScClient::EControlGetManufacturerStringDescriptor:
|
sl@0
|
2113 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetManufacturerStringDescriptor"));
|
sl@0
|
2114 |
r = iController->GetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2115 |
break;
|
sl@0
|
2116 |
|
sl@0
|
2117 |
case RDevUsbcScClient::EControlSetManufacturerStringDescriptor:
|
sl@0
|
2118 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetManufacturerStringDescriptor"));
|
sl@0
|
2119 |
r = iController->SetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2120 |
break;
|
sl@0
|
2121 |
|
sl@0
|
2122 |
case RDevUsbcScClient::EControlRemoveManufacturerStringDescriptor:
|
sl@0
|
2123 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveManufacturerStringDescriptor"));
|
sl@0
|
2124 |
r = iController->RemoveManufacturerStringDescriptor();
|
sl@0
|
2125 |
break;
|
sl@0
|
2126 |
|
sl@0
|
2127 |
case RDevUsbcScClient::EControlGetProductStringDescriptor:
|
sl@0
|
2128 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetProductStringDescriptor"));
|
sl@0
|
2129 |
r = iController->GetProductStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2130 |
break;
|
sl@0
|
2131 |
|
sl@0
|
2132 |
case RDevUsbcScClient::EControlSetProductStringDescriptor:
|
sl@0
|
2133 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetProductStringDescriptor"));
|
sl@0
|
2134 |
r = iController->SetProductStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2135 |
break;
|
sl@0
|
2136 |
|
sl@0
|
2137 |
case RDevUsbcScClient::EControlRemoveProductStringDescriptor:
|
sl@0
|
2138 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveProductStringDescriptor"));
|
sl@0
|
2139 |
r = iController->RemoveProductStringDescriptor();
|
sl@0
|
2140 |
break;
|
sl@0
|
2141 |
|
sl@0
|
2142 |
case RDevUsbcScClient::EControlGetSerialNumberStringDescriptor:
|
sl@0
|
2143 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetSerialNumberStringDescriptor"));
|
sl@0
|
2144 |
r = iController->GetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2145 |
break;
|
sl@0
|
2146 |
|
sl@0
|
2147 |
case RDevUsbcScClient::EControlSetSerialNumberStringDescriptor:
|
sl@0
|
2148 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetSerialNumberStringDescriptor"));
|
sl@0
|
2149 |
r = iController->SetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2150 |
break;
|
sl@0
|
2151 |
|
sl@0
|
2152 |
case RDevUsbcScClient::EControlRemoveSerialNumberStringDescriptor:
|
sl@0
|
2153 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveSerialNumberStringDescriptor"));
|
sl@0
|
2154 |
r = iController->RemoveSerialNumberStringDescriptor();
|
sl@0
|
2155 |
break;
|
sl@0
|
2156 |
|
sl@0
|
2157 |
case RDevUsbcScClient::EControlGetConfigurationStringDescriptor:
|
sl@0
|
2158 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationStringDescriptor"));
|
sl@0
|
2159 |
r = iController->GetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2160 |
break;
|
sl@0
|
2161 |
|
sl@0
|
2162 |
case RDevUsbcScClient::EControlSetConfigurationStringDescriptor:
|
sl@0
|
2163 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationStringDescriptor"));
|
sl@0
|
2164 |
r = iController->SetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
|
sl@0
|
2165 |
break;
|
sl@0
|
2166 |
|
sl@0
|
2167 |
case RDevUsbcScClient::EControlRemoveConfigurationStringDescriptor:
|
sl@0
|
2168 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveConfigurationStringDescriptor"));
|
sl@0
|
2169 |
r = iController->RemoveConfigurationStringDescriptor();
|
sl@0
|
2170 |
break;
|
sl@0
|
2171 |
|
sl@0
|
2172 |
case RDevUsbcScClient::EControlGetStringDescriptor:
|
sl@0
|
2173 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptor"));
|
sl@0
|
2174 |
r = iController->GetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
|
sl@0
|
2175 |
break;
|
sl@0
|
2176 |
|
sl@0
|
2177 |
case RDevUsbcScClient::EControlSetStringDescriptor:
|
sl@0
|
2178 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptor"));
|
sl@0
|
2179 |
r = iController->SetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
|
sl@0
|
2180 |
break;
|
sl@0
|
2181 |
|
sl@0
|
2182 |
case RDevUsbcScClient::EControlRemoveStringDescriptor:
|
sl@0
|
2183 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveStringDescriptor"));
|
sl@0
|
2184 |
r = iController->RemoveStringDescriptor((TUint8) (TInt) a1);
|
sl@0
|
2185 |
break;
|
sl@0
|
2186 |
|
sl@0
|
2187 |
case RDevUsbcScClient::EControlAllocateEndpointResource:
|
sl@0
|
2188 |
{
|
sl@0
|
2189 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlAllocateEndpointResource"));
|
sl@0
|
2190 |
epRes = (TUsbcEndpointResource)((TInt) a2);
|
sl@0
|
2191 |
TInt realEp=-1;
|
sl@0
|
2192 |
r = GetRealEpForEpResource((TInt)a1, realEp);
|
sl@0
|
2193 |
if (r==KErrNone)
|
sl@0
|
2194 |
r = iController->AllocateEndpointResource(this, realEp, epRes);
|
sl@0
|
2195 |
break;
|
sl@0
|
2196 |
}
|
sl@0
|
2197 |
case RDevUsbcScClient::EControlDeAllocateEndpointResource:
|
sl@0
|
2198 |
{
|
sl@0
|
2199 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlDeAllocateEndpointResource"));
|
sl@0
|
2200 |
epRes = (TUsbcEndpointResource)((TInt) a2);
|
sl@0
|
2201 |
TInt realEp=-1;
|
sl@0
|
2202 |
r = GetRealEpForEpResource((TInt)a1, realEp);
|
sl@0
|
2203 |
if (r==KErrNone)
|
sl@0
|
2204 |
r = iController->DeAllocateEndpointResource(this, realEp, epRes);
|
sl@0
|
2205 |
break;
|
sl@0
|
2206 |
}
|
sl@0
|
2207 |
case RDevUsbcScClient::EControlQueryEndpointResourceUse:
|
sl@0
|
2208 |
{
|
sl@0
|
2209 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlQueryEndpointResourceUse"));
|
sl@0
|
2210 |
epRes = (TUsbcEndpointResource)((TInt) a2);
|
sl@0
|
2211 |
TInt realEp=-1;
|
sl@0
|
2212 |
r = GetRealEpForEpResource((TInt)a1, realEp);
|
sl@0
|
2213 |
if (r==KErrNone)
|
sl@0
|
2214 |
r = iController->QueryEndpointResource(this, realEp, epRes);
|
sl@0
|
2215 |
break;
|
sl@0
|
2216 |
}
|
sl@0
|
2217 |
case RDevUsbcScClient::EControlSetOtgDescriptor:
|
sl@0
|
2218 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlSetOtgDescriptor"));
|
sl@0
|
2219 |
r = iController->SetOtgDescriptor(iClient, *((const TDesC8*)a1));
|
sl@0
|
2220 |
break;
|
sl@0
|
2221 |
|
sl@0
|
2222 |
case RDevUsbcScClient::EControlGetOtgDescriptor:
|
sl@0
|
2223 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetOtgDescriptor"));
|
sl@0
|
2224 |
r = iController->GetOtgDescriptor(iClient, *((TDes8*)a1));
|
sl@0
|
2225 |
break;
|
sl@0
|
2226 |
|
sl@0
|
2227 |
case RDevUsbcScClient::EControlGetOtgFeatures:
|
sl@0
|
2228 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlGetOtgFeatures"));
|
sl@0
|
2229 |
r = iController->GetOtgFeatures(iClient, *((TDes8*)a1));
|
sl@0
|
2230 |
break;
|
sl@0
|
2231 |
|
sl@0
|
2232 |
case RDevUsbcScClient::EControlRealizeInterface:
|
sl@0
|
2233 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlRealizeInterface"));
|
sl@0
|
2234 |
r = RealizeInterface();
|
sl@0
|
2235 |
break;
|
sl@0
|
2236 |
case RDevUsbcScClient::EControlStartNextInAlternateSetting:
|
sl@0
|
2237 |
__KTRACE_OPT(KUSB, Kern::Printf("EControlStartNextInAlternateSetting"));
|
sl@0
|
2238 |
r = StartNextInAlternateSetting();
|
sl@0
|
2239 |
break;
|
sl@0
|
2240 |
|
sl@0
|
2241 |
default:
|
sl@0
|
2242 |
__KTRACE_OPT(KUSB, Kern::Printf("Function code not supported"));
|
sl@0
|
2243 |
r = KErrNotSupported;
|
sl@0
|
2244 |
}
|
sl@0
|
2245 |
|
sl@0
|
2246 |
return r;
|
sl@0
|
2247 |
}
|
sl@0
|
2248 |
// end DoControl.
|
sl@0
|
2249 |
|
sl@0
|
2250 |
|
sl@0
|
2251 |
|
sl@0
|
2252 |
//
|
sl@0
|
2253 |
// Overriding DObject virtual
|
sl@0
|
2254 |
//
|
sl@0
|
2255 |
TInt DLddUsbcScChannel::RequestUserHandle(DThread* aThread, TOwnerType /*aType*/)
|
sl@0
|
2256 |
{
|
sl@0
|
2257 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::RequestUserHandle"));
|
sl@0
|
2258 |
// The USB client LDD is not designed for a channel to be shared between
|
sl@0
|
2259 |
// threads. It saves a pointer to the current thread when it is opened, and
|
sl@0
|
2260 |
// uses this to complete any asynchronous requests.
|
sl@0
|
2261 |
// It is therefore not acceptable for the handle to be duplicated and used
|
sl@0
|
2262 |
// by another thread:
|
sl@0
|
2263 |
if (aThread == iClient)
|
sl@0
|
2264 |
{
|
sl@0
|
2265 |
return KErrNone;
|
sl@0
|
2266 |
}
|
sl@0
|
2267 |
else
|
sl@0
|
2268 |
{
|
sl@0
|
2269 |
return KErrAccessDenied;
|
sl@0
|
2270 |
}
|
sl@0
|
2271 |
}
|
sl@0
|
2272 |
|
sl@0
|
2273 |
inline TInt DLddUsbcScChannel::GetRealEpForEpResource(TInt aEndpoint, TInt& aRealEp)
|
sl@0
|
2274 |
{
|
sl@0
|
2275 |
if (iEndpoint) // if we've enumerated at least once, proceed as normal.
|
sl@0
|
2276 |
{
|
sl@0
|
2277 |
if (aEndpoint <= iNumberOfEndpoints && aEndpoint >= 0)
|
sl@0
|
2278 |
{
|
sl@0
|
2279 |
aRealEp=iEndpoint[aEndpoint]->RealEpNumber();
|
sl@0
|
2280 |
return KErrNone;
|
sl@0
|
2281 |
}
|
sl@0
|
2282 |
}
|
sl@0
|
2283 |
else // Assume alternate setting 0.
|
sl@0
|
2284 |
{
|
sl@0
|
2285 |
if (iAlternateSettingList) // Check it has been set up.
|
sl@0
|
2286 |
{
|
sl@0
|
2287 |
TUsbcScAlternateSetting* alt = iAlternateSettingList->iHead;
|
sl@0
|
2288 |
if (alt && (aEndpoint <= alt->iNumberOfEndpoints && aEndpoint >= 0))
|
sl@0
|
2289 |
{
|
sl@0
|
2290 |
aRealEp= alt->iEndpoint[aEndpoint]->RealEpNumber();
|
sl@0
|
2291 |
return KErrNone;
|
sl@0
|
2292 |
}
|
sl@0
|
2293 |
}
|
sl@0
|
2294 |
}
|
sl@0
|
2295 |
return KErrUsbDeviceNotConfigured;
|
sl@0
|
2296 |
}
|
sl@0
|
2297 |
|
sl@0
|
2298 |
|
sl@0
|
2299 |
TUsbcEndpointInfoArray::TUsbcEndpointInfoArray(const TUsbcScEndpointInfo* aData, TInt aDataSize)
|
sl@0
|
2300 |
{
|
sl@0
|
2301 |
iType = EUsbcScEndpointInfo;
|
sl@0
|
2302 |
iData = (TUint8*) aData;
|
sl@0
|
2303 |
if (aDataSize>0)
|
sl@0
|
2304 |
iDataSize = aDataSize;
|
sl@0
|
2305 |
else
|
sl@0
|
2306 |
iDataSize = sizeof(TUsbcScEndpointInfo);
|
sl@0
|
2307 |
}
|
sl@0
|
2308 |
|
sl@0
|
2309 |
|
sl@0
|
2310 |
//
|
sl@0
|
2311 |
// SetInterface
|
sl@0
|
2312 |
//
|
sl@0
|
2313 |
// Called from DoControl. Sets the configuration of a given Interface. // Needs changing
|
sl@0
|
2314 |
// All interfaces must be configured before one can be used.
|
sl@0
|
2315 |
//
|
sl@0
|
2316 |
|
sl@0
|
2317 |
TInt DLddUsbcScChannel::SetInterface(TInt aInterfaceNumber, TUsbcScIfcInfo* aInfoBuf)
|
sl@0
|
2318 |
{
|
sl@0
|
2319 |
// Copy interface description.
|
sl@0
|
2320 |
|
sl@0
|
2321 |
if (iRealizeCalled)
|
sl@0
|
2322 |
return KErrUsbAlreadyRealized;
|
sl@0
|
2323 |
|
sl@0
|
2324 |
if (!iAlternateSettingList)
|
sl@0
|
2325 |
{
|
sl@0
|
2326 |
iAlternateSettingList = new TUsbcScAlternateSettingList;
|
sl@0
|
2327 |
if (iAlternateSettingList==NULL)
|
sl@0
|
2328 |
{
|
sl@0
|
2329 |
return KErrNoMemory;
|
sl@0
|
2330 |
}
|
sl@0
|
2331 |
}
|
sl@0
|
2332 |
|
sl@0
|
2333 |
// Read descriptor in
|
sl@0
|
2334 |
TUsbcScInterfaceInfoBuf ifc_info_buf;
|
sl@0
|
2335 |
TUsbcScInterfaceInfoBuf* const ifc_info_buf_ptr = aInfoBuf->iInterfaceData;
|
sl@0
|
2336 |
const TInt srcLen = Kern::ThreadGetDesLength(iClient, ifc_info_buf_ptr);
|
sl@0
|
2337 |
|
sl@0
|
2338 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface srcLen = %d len = %d", srcLen, ifc_info_buf.Length() ));
|
sl@0
|
2339 |
|
sl@0
|
2340 |
if (srcLen < ifc_info_buf.Length())
|
sl@0
|
2341 |
{
|
sl@0
|
2342 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface can't copy"));
|
sl@0
|
2343 |
PanicClientThread(EDesOverflow);
|
sl@0
|
2344 |
}
|
sl@0
|
2345 |
|
sl@0
|
2346 |
TInt r = Kern::ThreadDesRead(iClient, ifc_info_buf_ptr, ifc_info_buf, 0, KChunkShiftBy0);
|
sl@0
|
2347 |
if (r != KErrNone)
|
sl@0
|
2348 |
{
|
sl@0
|
2349 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface Copy failed reason=%d", r));
|
sl@0
|
2350 |
PanicClientThread(r);
|
sl@0
|
2351 |
}
|
sl@0
|
2352 |
|
sl@0
|
2353 |
// The list of endpoints is within the interface info.
|
sl@0
|
2354 |
TUsbcScEndpointInfo* pEndpointData = ifc_info_buf().iEndpointData;
|
sl@0
|
2355 |
|
sl@0
|
2356 |
const TInt num_endpoints = ifc_info_buf().iTotalEndpointsUsed;
|
sl@0
|
2357 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface num_endpoints=%d", num_endpoints));
|
sl@0
|
2358 |
if (num_endpoints>KMaxEndpointsPerClient)
|
sl@0
|
2359 |
return KErrOverflow;
|
sl@0
|
2360 |
|
sl@0
|
2361 |
|
sl@0
|
2362 |
// Initialize real ep numbers list.
|
sl@0
|
2363 |
TInt i;
|
sl@0
|
2364 |
TInt real_ep_numbers[KMaxEndpointsPerClient+1]; // range 1->KMaxEndpointsPerClient (0 not used)
|
sl@0
|
2365 |
for (i=0; i<=KMaxEndpointsPerClient; i++)
|
sl@0
|
2366 |
real_ep_numbers[i] = -1;
|
sl@0
|
2367 |
|
sl@0
|
2368 |
|
sl@0
|
2369 |
// See if PIL will accept this interface
|
sl@0
|
2370 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface Calling controller"));
|
sl@0
|
2371 |
TUsbcEndpointInfoArray endpointData = TUsbcEndpointInfoArray(ifc_info_buf().iEndpointData);
|
sl@0
|
2372 |
|
sl@0
|
2373 |
r = iController->SetInterface(this,
|
sl@0
|
2374 |
iClient,
|
sl@0
|
2375 |
aInterfaceNumber,
|
sl@0
|
2376 |
ifc_info_buf().iClass,
|
sl@0
|
2377 |
aInfoBuf->iString,
|
sl@0
|
2378 |
(TInt) ifc_info_buf().iTotalEndpointsUsed,
|
sl@0
|
2379 |
endpointData,
|
sl@0
|
2380 |
&real_ep_numbers[0],
|
sl@0
|
2381 |
ifc_info_buf().iFeatureWord);
|
sl@0
|
2382 |
|
sl@0
|
2383 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface controller returned %d", r));
|
sl@0
|
2384 |
if (r != KErrNone)
|
sl@0
|
2385 |
{
|
sl@0
|
2386 |
__KTRACE_OPT(KPANIC, Kern::Printf("SetInterface failed reason=%d", r));
|
sl@0
|
2387 |
return r;
|
sl@0
|
2388 |
}
|
sl@0
|
2389 |
|
sl@0
|
2390 |
// create alternate setting record
|
sl@0
|
2391 |
TUsbcScAlternateSetting* alternateSettingListRec = new TUsbcScAlternateSetting;
|
sl@0
|
2392 |
if (!alternateSettingListRec)
|
sl@0
|
2393 |
{
|
sl@0
|
2394 |
r = KErrNoMemory;
|
sl@0
|
2395 |
goto ReleaseInterface;
|
sl@0
|
2396 |
}
|
sl@0
|
2397 |
|
sl@0
|
2398 |
// other endpoints
|
sl@0
|
2399 |
for (TInt i = 1; i <= num_endpoints; i++, pEndpointData++)
|
sl@0
|
2400 |
{
|
sl@0
|
2401 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d", i));
|
sl@0
|
2402 |
|
sl@0
|
2403 |
if ((pEndpointData->iType==KUsbEpTypeControl)
|
sl@0
|
2404 |
|| (pEndpointData->iDir != KUsbEpDirIn && pEndpointData->iDir != KUsbEpDirOut)
|
sl@0
|
2405 |
|| (pEndpointData->iSize > 1024) || (pEndpointData->iSize<=0))
|
sl@0
|
2406 |
{
|
sl@0
|
2407 |
r = KErrUsbBadEndpoint;
|
sl@0
|
2408 |
goto CleanUp;
|
sl@0
|
2409 |
}
|
sl@0
|
2410 |
// Check data
|
sl@0
|
2411 |
|
sl@0
|
2412 |
TUint* bufferSize = &(pEndpointData->iBufferSize);
|
sl@0
|
2413 |
if (*bufferSize==0)
|
sl@0
|
2414 |
*bufferSize= KUsbcScDefaultBufferSize;
|
sl@0
|
2415 |
|
sl@0
|
2416 |
TInt pageSize = Kern::RoundToPageSize(1);
|
sl@0
|
2417 |
// Round buffersize up to nearest pagesize.
|
sl@0
|
2418 |
*bufferSize = (*bufferSize+pageSize-1) & ~(pageSize-1);
|
sl@0
|
2419 |
|
sl@0
|
2420 |
TUsbcScEndpoint* ep = new TUsbcScEndpoint(this, iController, pEndpointData, i);
|
sl@0
|
2421 |
alternateSettingListRec->iEndpoint[i] = ep;
|
sl@0
|
2422 |
if (!ep)
|
sl@0
|
2423 |
{
|
sl@0
|
2424 |
r = KErrNoMemory;
|
sl@0
|
2425 |
goto CleanUp;
|
sl@0
|
2426 |
}
|
sl@0
|
2427 |
if (ep->Construct() != KErrNone)
|
sl@0
|
2428 |
{
|
sl@0
|
2429 |
r = KErrNoMemory;
|
sl@0
|
2430 |
goto CleanUp;
|
sl@0
|
2431 |
}
|
sl@0
|
2432 |
|
sl@0
|
2433 |
|
sl@0
|
2434 |
__KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d rec=0x%08x ep==0x%08x",
|
sl@0
|
2435 |
i, alternateSettingListRec, ep));
|
sl@0
|
2436 |
}
|
sl@0
|
2437 |
|
sl@0
|
2438 |
if (iAlternateSettingList->iHead)
|
sl@0
|
2439 |
{
|
sl@0
|
2440 |
iAlternateSettingList->iTail->iNext = alternateSettingListRec;
|
sl@0
|
2441 |
alternateSettingListRec->iPrevious = iAlternateSettingList->iTail;
|
sl@0
|
2442 |
iAlternateSettingList->iTail = alternateSettingListRec;
|
sl@0
|
2443 |
}
|
sl@0
|
2444 |
else
|
sl@0
|
2445 |
{
|
sl@0
|
2446 |
iAlternateSettingList->iHead = alternateSettingListRec;
|
sl@0
|
2447 |
iAlternateSettingList->iTail = alternateSettingListRec;
|
sl@0
|
2448 |
}
|
sl@0
|
2449 |
|
sl@0
|
2450 |
alternateSettingListRec->iNext = NULL;
|
sl@0
|
2451 |
alternateSettingListRec->iSetting = aInterfaceNumber;
|
sl@0
|
2452 |
alternateSettingListRec->iNumberOfEndpoints = num_endpoints;
|
sl@0
|
2453 |
|
sl@0
|
2454 |
// Record the 'real' endpoint number used by the PDD in both the Ep and
|
sl@0
|
2455 |
// the Req callback:
|
sl@0
|
2456 |
for (TInt i = 1; i <= num_endpoints; i++)
|
sl@0
|
2457 |
{
|
sl@0
|
2458 |
alternateSettingListRec->iEndpoint[i]->SetRealEpNumber(real_ep_numbers[i]);
|
sl@0
|
2459 |
}
|
sl@0
|
2460 |
|
sl@0
|
2461 |
return KErrNone;
|
sl@0
|
2462 |
|
sl@0
|
2463 |
CleanUp:
|
sl@0
|
2464 |
delete alternateSettingListRec;
|
sl@0
|
2465 |
//Fall Through
|
sl@0
|
2466 |
|
sl@0
|
2467 |
ReleaseInterface:
|
sl@0
|
2468 |
#if _DEBUG
|
sl@0
|
2469 |
TInt r1 = iController->ReleaseInterface(this, aInterfaceNumber);
|
sl@0
|
2470 |
__KTRACE_OPT(KUSB, Kern::Printf("Release Interface controller returned %d", r1));
|
sl@0
|
2471 |
#else
|
sl@0
|
2472 |
(void) iController->ReleaseInterface(this, aInterfaceNumber);
|
sl@0
|
2473 |
#endif
|
sl@0
|
2474 |
return r;
|
sl@0
|
2475 |
}
|
sl@0
|
2476 |
// end SetInterface
|
sl@0
|
2477 |
|
sl@0
|
2478 |
|
sl@0
|
2479 |
|
sl@0
|
2480 |
#ifdef _DEBUG
|
sl@0
|
2481 |
void RealizeInterface_Dump(TUint* aMem)
|
sl@0
|
2482 |
{
|
sl@0
|
2483 |
TUint *mem= NULL;
|
sl@0
|
2484 |
__KTRACE_OPT(KUSB, mem = aMem);
|
sl@0
|
2485 |
if (mem!=NULL)
|
sl@0
|
2486 |
{
|
sl@0
|
2487 |
TInt j;
|
sl@0
|
2488 |
Kern::Printf("Final chunk header State:");
|
sl@0
|
2489 |
for (j=0; j<30; j+=8)
|
sl@0
|
2490 |
Kern::Printf("%2x: %8x %8x %8x %8x %8x %8x %8x %8x", j, mem[j], mem[j+1], mem[j+2], mem[j+3], mem[j+4], mem[j+5], mem[j+6], mem[j+7] );
|
sl@0
|
2491 |
};
|
sl@0
|
2492 |
};
|
sl@0
|
2493 |
#endif
|
sl@0
|
2494 |
|
sl@0
|
2495 |
|
sl@0
|
2496 |
/*
|
sl@0
|
2497 |
Chunk Created, filled with structure, and passed back to userside.
|
sl@0
|
2498 |
*/
|
sl@0
|
2499 |
TInt DLddUsbcScChannel::RealizeInterface(void)
|
sl@0
|
2500 |
{
|
sl@0
|
2501 |
if (iRealizeCalled)
|
sl@0
|
2502 |
return KErrUsbAlreadyRealized;
|
sl@0
|
2503 |
|
sl@0
|
2504 |
TRealizeInfo bufInfo;
|
sl@0
|
2505 |
|
sl@0
|
2506 |
TInt errorOrChunk = KErrNone;
|
sl@0
|
2507 |
TBool openedCS = EFalse;
|
sl@0
|
2508 |
TInt offset =0;
|
sl@0
|
2509 |
|
sl@0
|
2510 |
// Start by creating a temporary scratchpad for endpoint calculations.
|
sl@0
|
2511 |
bufInfo.Init(iAlternateSettingList);
|
sl@0
|
2512 |
|
sl@0
|
2513 |
// Fill in our scratchpad with all the required endpoints, sorting them
|
sl@0
|
2514 |
// in order of size required.
|
sl@0
|
2515 |
errorOrChunk = bufInfo.CopyAndSortEndpoints();
|
sl@0
|
2516 |
if (errorOrChunk!=KErrNone)
|
sl@0
|
2517 |
{
|
sl@0
|
2518 |
goto realize_end;
|
sl@0
|
2519 |
}
|
sl@0
|
2520 |
|
sl@0
|
2521 |
// We now have endpoints sorted in order of size for each altsetting.
|
sl@0
|
2522 |
// The very largest for each endpoint will share the first buffer, and all of
|
sl@0
|
2523 |
// the second largest ends points will share the second buffer, and so on.
|
sl@0
|
2524 |
// Find the highest buffer size for each row, to determine the buffer size,
|
sl@0
|
2525 |
// and keep a total of total space needed.
|
sl@0
|
2526 |
bufInfo.CalcBuffSizes();
|
sl@0
|
2527 |
|
sl@0
|
2528 |
// We now have the max sizes wanted for each endpoint buffer.
|
sl@0
|
2529 |
// we also have to total size for all endpoints.
|
sl@0
|
2530 |
// and finally we have the total number of buffers.
|
sl@0
|
2531 |
|
sl@0
|
2532 |
// Add on size for header, then add on size for guard pages.
|
sl@0
|
2533 |
bufInfo.iTotalSize+= KHeaderSize + bufInfo.iTotalBuffers * KGuardSize;
|
sl@0
|
2534 |
|
sl@0
|
2535 |
// Create shared Chunk . . . . . . . . . .
|
sl@0
|
2536 |
if (iChunkInfo==NULL)
|
sl@0
|
2537 |
{
|
sl@0
|
2538 |
NKern::ThreadEnterCS();
|
sl@0
|
2539 |
openedCS = ETrue;
|
sl@0
|
2540 |
errorOrChunk = TUsbcScChunkInfo::New(iChunkInfo, bufInfo.iTotalSize, (DLogicalDevice*) iDevice);
|
sl@0
|
2541 |
if (errorOrChunk!=KErrNone)
|
sl@0
|
2542 |
{
|
sl@0
|
2543 |
goto realize_end;
|
sl@0
|
2544 |
}
|
sl@0
|
2545 |
}
|
sl@0
|
2546 |
else
|
sl@0
|
2547 |
{
|
sl@0
|
2548 |
// As of writing, the was no way for iChunk to be anything other then NULL.
|
sl@0
|
2549 |
// You cannot 'unrealise' and iChunk cannot be set any other way.
|
sl@0
|
2550 |
Kern::Fault("DLddUsbcScChannel::RealizeInterface", __LINE__);
|
sl@0
|
2551 |
}
|
sl@0
|
2552 |
|
sl@0
|
2553 |
// Populate the shared chunk . . . . . . .
|
sl@0
|
2554 |
|
sl@0
|
2555 |
|
sl@0
|
2556 |
// First create chunk header.
|
sl@0
|
2557 |
errorOrChunk = iChunkInfo->ChunkAlloc(offset, KHeaderSize);
|
sl@0
|
2558 |
if (errorOrChunk!=KErrNone)
|
sl@0
|
2559 |
{
|
sl@0
|
2560 |
if (errorOrChunk==-KErrNoMemory)
|
sl@0
|
2561 |
errorOrChunk=KErrNoMemory;
|
sl@0
|
2562 |
goto realize_end;
|
sl@0
|
2563 |
}
|
sl@0
|
2564 |
|
sl@0
|
2565 |
|
sl@0
|
2566 |
offset+=KHeaderSize + KGuardSize; // Also any more for EP0?
|
sl@0
|
2567 |
|
sl@0
|
2568 |
// Next, lay out the geometry of the chunk header.
|
sl@0
|
2569 |
|
sl@0
|
2570 |
bufInfo.LayoutChunkHeader(iChunkInfo);
|
sl@0
|
2571 |
|
sl@0
|
2572 |
|
sl@0
|
2573 |
{ // Scope ep0Size
|
sl@0
|
2574 |
TInt ep0Size=0;
|
sl@0
|
2575 |
|
sl@0
|
2576 |
// Create K-side buffer table
|
sl@0
|
2577 |
if (!iBuffers)
|
sl@0
|
2578 |
iBuffers = (TUsbcScBuffer *) Kern::AllocZ(sizeof(TUsbcScBuffer) * (bufInfo.iTotalBuffers+2)); // +2 is for ep0.
|
sl@0
|
2579 |
if (!iBuffers)
|
sl@0
|
2580 |
{
|
sl@0
|
2581 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Error: Alloc iBufers failed!"));
|
sl@0
|
2582 |
errorOrChunk = KErrNoMemory;
|
sl@0
|
2583 |
goto realize_end;
|
sl@0
|
2584 |
}
|
sl@0
|
2585 |
|
sl@0
|
2586 |
|
sl@0
|
2587 |
errorOrChunk = SetupEp0();
|
sl@0
|
2588 |
if (errorOrChunk)
|
sl@0
|
2589 |
{
|
sl@0
|
2590 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: SetupEp0 . ERROR %d",errorOrChunk));
|
sl@0
|
2591 |
goto realize_end;
|
sl@0
|
2592 |
}
|
sl@0
|
2593 |
|
sl@0
|
2594 |
ep0Size = iEp0Endpoint->EndpointInfo()->iSize;
|
sl@0
|
2595 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Setup EP0. max packet size %d", ep0Size));
|
sl@0
|
2596 |
|
sl@0
|
2597 |
// Create EP0 buffers
|
sl@0
|
2598 |
iEP0OutBuff=bufInfo.iTotalBuffers;
|
sl@0
|
2599 |
errorOrChunk = iBuffers[iEP0OutBuff].Construct(KUsbcScBiOut, this, KUsbScEP0OutBufPos, KUsbScEP0OutBufEnd, ep0Size, ep0Size, ep0Size);
|
sl@0
|
2600 |
if (errorOrChunk)
|
sl@0
|
2601 |
{
|
sl@0
|
2602 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Setup EP0 Out. ERROR %d",errorOrChunk));
|
sl@0
|
2603 |
goto realize_end;
|
sl@0
|
2604 |
}
|
sl@0
|
2605 |
|
sl@0
|
2606 |
iBuffers[iEP0OutBuff].CreateChunkBufferHeader();
|
sl@0
|
2607 |
iBuffers[iEP0OutBuff].iCallback = iEp0Endpoint->iRequestCallbackInfo;
|
sl@0
|
2608 |
((TUsbcScBufferRecord*) &(
|
sl@0
|
2609 |
bufInfo.iChunkStuct->iBufferOffset[KUsbcScEp0OutBuff*sizeof(TUsbcScBufferRecord)]
|
sl@0
|
2610 |
)) ->Set(KUsbScEP0OutBufPos, KUsbScEP0OutBufEnd);
|
sl@0
|
2611 |
|
sl@0
|
2612 |
|
sl@0
|
2613 |
iEP0InBuff=bufInfo.iTotalBuffers+1;
|
sl@0
|
2614 |
errorOrChunk = iBuffers[iEP0InBuff].Construct( KUsbcScBiIn , this, KUsbScEP0InBufPos , KUsbScEP0InBufEnd , ep0Size, ep0Size, ep0Size);
|
sl@0
|
2615 |
if (errorOrChunk)
|
sl@0
|
2616 |
{
|
sl@0
|
2617 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Setup EP0 In. ERROR %d",errorOrChunk));
|
sl@0
|
2618 |
goto realize_end;
|
sl@0
|
2619 |
}
|
sl@0
|
2620 |
|
sl@0
|
2621 |
iBuffers[iEP0InBuff].iCallback = iEp0Endpoint->iRequestCallbackInfo;
|
sl@0
|
2622 |
|
sl@0
|
2623 |
((TUsbcScBufferRecord*) &(
|
sl@0
|
2624 |
bufInfo.iChunkStuct->iBufferOffset[KUsbcScEp0InBuff*sizeof(TUsbcScBufferRecord)]
|
sl@0
|
2625 |
))->Set(KUsbScEP0InBufPos, KUsbScEP0InBufEnd);
|
sl@0
|
2626 |
|
sl@0
|
2627 |
|
sl@0
|
2628 |
} // end ep0Size scope
|
sl@0
|
2629 |
|
sl@0
|
2630 |
// Create resources and tables. . . . . .
|
sl@0
|
2631 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: Create resources tables"));
|
sl@0
|
2632 |
|
sl@0
|
2633 |
{ // scope of bufNum
|
sl@0
|
2634 |
// For each EP buffer
|
sl@0
|
2635 |
TInt buffNum=0;
|
sl@0
|
2636 |
TInt buffMinSize;
|
sl@0
|
2637 |
TInt endpointNumber;
|
sl@0
|
2638 |
TUsbcScEndpoint* endpointRecord;
|
sl@0
|
2639 |
TInt endpoint;
|
sl@0
|
2640 |
TInt inout;
|
sl@0
|
2641 |
TEndpointSortBufs* bufsd;
|
sl@0
|
2642 |
TUsbcScHdrEndpointRecord* epRecord;
|
sl@0
|
2643 |
for (endpoint=0; endpoint<bufInfo.iMaxEndpoints; endpoint++) // endpoint = buf row.
|
sl@0
|
2644 |
{
|
sl@0
|
2645 |
for (inout=KUsbcScIn; inout<KUsbcScDirections; inout++)
|
sl@0
|
2646 |
{
|
sl@0
|
2647 |
buffMinSize = KUsbSc_BigBuff_MinimumRamRun;
|
sl@0
|
2648 |
|
sl@0
|
2649 |
TInt needed = bufInfo.iBufs[inout].iSizes[endpoint];
|
sl@0
|
2650 |
if (needed)
|
sl@0
|
2651 |
{
|
sl@0
|
2652 |
TInt bufStart = offset;
|
sl@0
|
2653 |
|
sl@0
|
2654 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: buf row:%d inout %d, iBufferOffset[%d+2]=%x",endpoint, inout, buffNum, bufStart));
|
sl@0
|
2655 |
|
sl@0
|
2656 |
bufsd = &(bufInfo.iBufs[inout]);
|
sl@0
|
2657 |
// and then point all endpoints that use it, towards it.
|
sl@0
|
2658 |
TInt altSetting;
|
sl@0
|
2659 |
TUint maxReadSize = ~0;
|
sl@0
|
2660 |
for (altSetting=0; altSetting < bufInfo.iAltSettings; altSetting++)
|
sl@0
|
2661 |
{
|
sl@0
|
2662 |
endpointRecord =bufsd->iEp[altSetting*bufInfo.iMaxEndpoints + endpoint];
|
sl@0
|
2663 |
if (endpointRecord)
|
sl@0
|
2664 |
{
|
sl@0
|
2665 |
endpointNumber = endpointRecord->EpNumber();
|
sl@0
|
2666 |
endpointRecord->SetBuffer(&iBuffers[buffNum]);
|
sl@0
|
2667 |
|
sl@0
|
2668 |
epRecord = (TUsbcScHdrEndpointRecord*) &iChunkInfo->iChunkMem[
|
sl@0
|
2669 |
(bufInfo.iAltSettingsTbl->iAltTableOffset[altSetting]) // i.e. Just after altSettingsTbl
|
sl@0
|
2670 |
+sizeof(TInt) // after number of endpoints field
|
sl@0
|
2671 |
+(endpointNumber-1)*sizeof(TUsbcScHdrEndpointRecord)
|
sl@0
|
2672 |
];
|
sl@0
|
2673 |
epRecord->iBufferNo = (TUint8) buffNum;
|
sl@0
|
2674 |
|
sl@0
|
2675 |
TInt epType=(endpointRecord->EndpointInfo()->iType);
|
sl@0
|
2676 |
epType= (epType& KUsbEpTypeControl)?KUsbScHdrEpTypeControl:
|
sl@0
|
2677 |
(epType& KUsbEpTypeIsochronous)?KUsbScHdrEpTypeIsochronous:
|
sl@0
|
2678 |
(epType& KUsbEpTypeBulk)?KUsbScHdrEpTypeBulk:
|
sl@0
|
2679 |
(epType& KUsbEpTypeInterrupt)?KUsbScHdrEpTypeInterrupt:KUsbScHdrEpTypeUnknown;
|
sl@0
|
2680 |
|
sl@0
|
2681 |
epRecord->iType = (inout+1) | (epType<<2);
|
sl@0
|
2682 |
|
sl@0
|
2683 |
if (endpointRecord->EndpointInfo()->iReadSize)
|
sl@0
|
2684 |
maxReadSize = (maxReadSize <= endpointRecord->EndpointInfo()->iReadSize) ? maxReadSize : endpointRecord->EndpointInfo()->iReadSize;
|
sl@0
|
2685 |
|
sl@0
|
2686 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: endpointNum %d in altSetting %d, alt table @ %d",
|
sl@0
|
2687 |
endpointNumber, altSetting,bufInfo.iAltSettingsTbl->iAltTableOffset[altSetting]));
|
sl@0
|
2688 |
}
|
sl@0
|
2689 |
else
|
sl@0
|
2690 |
{
|
sl@0
|
2691 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: endpointNum NA in altSetting %d", altSetting));
|
sl@0
|
2692 |
}
|
sl@0
|
2693 |
|
sl@0
|
2694 |
} // end for
|
sl@0
|
2695 |
|
sl@0
|
2696 |
|
sl@0
|
2697 |
// Alloc memory for buffer.
|
sl@0
|
2698 |
TInt grabSize = needed;
|
sl@0
|
2699 |
// Generally, a buffer fragmented into smaller memory regions will reduce the efficiency
|
sl@0
|
2700 |
// of reading or writing data, and so avoiding the allocation of very small sections
|
sl@0
|
2701 |
// is advantageous.
|
sl@0
|
2702 |
// However, if only a small amount is being allocated to start with, it is likely
|
sl@0
|
2703 |
// smaller amounts of data are to be sent (reducing this advantage), and 1 memory page
|
sl@0
|
2704 |
// is a much bigger proportion of the buffer, and so more worth allocating individually.
|
sl@0
|
2705 |
|
sl@0
|
2706 |
TInt minimumGrab;
|
sl@0
|
2707 |
if (needed<KUsbScBigBuffIs)
|
sl@0
|
2708 |
{
|
sl@0
|
2709 |
minimumGrab=Kern::RoundToPageSize(1);
|
sl@0
|
2710 |
buffMinSize = KUsbSc_SmallBuff_MinimumRamRun; // 1k
|
sl@0
|
2711 |
}
|
sl@0
|
2712 |
else
|
sl@0
|
2713 |
{
|
sl@0
|
2714 |
minimumGrab = buffMinSize+Kern::RoundToPageSize(1);
|
sl@0
|
2715 |
}
|
sl@0
|
2716 |
|
sl@0
|
2717 |
// Grab required memory, in bits as big as possible, down to the minimum size.
|
sl@0
|
2718 |
while (needed >= minimumGrab)
|
sl@0
|
2719 |
{
|
sl@0
|
2720 |
TInt r;
|
sl@0
|
2721 |
r = iChunkInfo->ChunkAlloc(offset, grabSize);
|
sl@0
|
2722 |
if (r==KErrNone)
|
sl@0
|
2723 |
{
|
sl@0
|
2724 |
offset+=grabSize;
|
sl@0
|
2725 |
needed-=grabSize;
|
sl@0
|
2726 |
}
|
sl@0
|
2727 |
else
|
sl@0
|
2728 |
{
|
sl@0
|
2729 |
if (r==-KErrNoMemory)
|
sl@0
|
2730 |
{
|
sl@0
|
2731 |
grabSize>>=1;
|
sl@0
|
2732 |
}
|
sl@0
|
2733 |
if ((grabSize<minimumGrab) || (r!=-KErrNoMemory))
|
sl@0
|
2734 |
{
|
sl@0
|
2735 |
errorOrChunk = r;
|
sl@0
|
2736 |
goto realize_end;
|
sl@0
|
2737 |
}
|
sl@0
|
2738 |
}
|
sl@0
|
2739 |
} // end while needed
|
sl@0
|
2740 |
|
sl@0
|
2741 |
// Initialize buffer
|
sl@0
|
2742 |
iBuffers[buffNum].Construct(inout, this, bufStart, offset, buffMinSize, 0, maxReadSize);
|
sl@0
|
2743 |
iBuffers[buffNum].CreateChunkBufferHeader();
|
sl@0
|
2744 |
((TUsbcScBufferRecord*) &(
|
sl@0
|
2745 |
bufInfo.iChunkStuct->iBufferOffset[(buffNum+2)*sizeof(TUsbcScBufferRecord)]
|
sl@0
|
2746 |
))->Set(bufStart, offset);
|
sl@0
|
2747 |
|
sl@0
|
2748 |
|
sl@0
|
2749 |
// inc pointers for next buffer
|
sl@0
|
2750 |
buffNum++;
|
sl@0
|
2751 |
offset+=KGuardSize;
|
sl@0
|
2752 |
} // end if needed
|
sl@0
|
2753 |
|
sl@0
|
2754 |
} // end for inout
|
sl@0
|
2755 |
} // end for each buffer
|
sl@0
|
2756 |
} // scope of bufNum
|
sl@0
|
2757 |
|
sl@0
|
2758 |
#ifdef _DEBUG
|
sl@0
|
2759 |
RealizeInterface_Dump((TUint*) iChunkInfo->iChunkMem); // Debug only tracing
|
sl@0
|
2760 |
#endif
|
sl@0
|
2761 |
|
sl@0
|
2762 |
realize_end:
|
sl@0
|
2763 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: cleanup. Err=%d", errorOrChunk));
|
sl@0
|
2764 |
// Here we clean up after either success, or after bailing out early.
|
sl@0
|
2765 |
|
sl@0
|
2766 |
bufInfo.Free();
|
sl@0
|
2767 |
|
sl@0
|
2768 |
if (iChunkInfo)
|
sl@0
|
2769 |
{
|
sl@0
|
2770 |
if (errorOrChunk==KErrNone)
|
sl@0
|
2771 |
{
|
sl@0
|
2772 |
// Everything is looking good - create RChunk for Userside.
|
sl@0
|
2773 |
errorOrChunk = Kern::MakeHandleAndOpen(iClient, iChunkInfo->iChunk);
|
sl@0
|
2774 |
iRealizeCalled = (errorOrChunk>=0);
|
sl@0
|
2775 |
} // endif errorOrChunk
|
sl@0
|
2776 |
|
sl@0
|
2777 |
if (errorOrChunk<0) // If error, destroy the chunk.
|
sl@0
|
2778 |
{
|
sl@0
|
2779 |
iChunkInfo->Close();
|
sl@0
|
2780 |
// ChunkInfo will delete itself with DFC, but the pointer here is no longer needed.
|
sl@0
|
2781 |
iChunkInfo=NULL;
|
sl@0
|
2782 |
|
sl@0
|
2783 |
// Destroy iBuffers
|
sl@0
|
2784 |
if (iBuffers)
|
sl@0
|
2785 |
{
|
sl@0
|
2786 |
TInt i;
|
sl@0
|
2787 |
for (i=0; i<(iNumBuffers+2); i++)
|
sl@0
|
2788 |
{
|
sl@0
|
2789 |
iBuffers[i].iStatusList.Destroy();
|
sl@0
|
2790 |
}
|
sl@0
|
2791 |
Kern::Free(iBuffers);
|
sl@0
|
2792 |
iBuffers=NULL;
|
sl@0
|
2793 |
}
|
sl@0
|
2794 |
|
sl@0
|
2795 |
}
|
sl@0
|
2796 |
else
|
sl@0
|
2797 |
{
|
sl@0
|
2798 |
iNumBuffers = bufInfo.iTotalBuffers;
|
sl@0
|
2799 |
iValidInterface = ETrue; // Let the games commence!
|
sl@0
|
2800 |
}
|
sl@0
|
2801 |
|
sl@0
|
2802 |
} // endif iChunkInfo
|
sl@0
|
2803 |
if (openedCS)
|
sl@0
|
2804 |
NKern::ThreadLeaveCS();
|
sl@0
|
2805 |
|
sl@0
|
2806 |
__KTRACE_OPT(KUSB, Kern::Printf("Realize: returning %x (%d)", errorOrChunk, errorOrChunk));
|
sl@0
|
2807 |
return errorOrChunk;
|
sl@0
|
2808 |
} // End RealizeInterface
|
sl@0
|
2809 |
|
sl@0
|
2810 |
|
sl@0
|
2811 |
//
|
sl@0
|
2812 |
// DestroyAllInterfaces
|
sl@0
|
2813 |
//
|
sl@0
|
2814 |
|
sl@0
|
2815 |
void DLddUsbcScChannel::DestroyAllInterfaces()
|
sl@0
|
2816 |
{
|
sl@0
|
2817 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::DestroyAllInterfaces"));
|
sl@0
|
2818 |
// Removes all interfaces
|
sl@0
|
2819 |
if (iAlternateSettingList)
|
sl@0
|
2820 |
{
|
sl@0
|
2821 |
if (iAlternateSettingList->iHead != NULL)
|
sl@0
|
2822 |
{
|
sl@0
|
2823 |
TUsbcScAlternateSetting* alternateSettingListRec = iAlternateSettingList->iTail;
|
sl@0
|
2824 |
while (alternateSettingListRec)
|
sl@0
|
2825 |
{
|
sl@0
|
2826 |
iAlternateSettingList->iTail = alternateSettingListRec->iPrevious;
|
sl@0
|
2827 |
// If this contains NULL now that is only possible if the record to be deleted was at the head
|
sl@0
|
2828 |
__KTRACE_OPT(KUSB, Kern::Printf("Release interface %d \n", alternateSettingListRec->iSetting));
|
sl@0
|
2829 |
iController->ReleaseInterface(this, alternateSettingListRec->iSetting);
|
sl@0
|
2830 |
delete alternateSettingListRec;
|
sl@0
|
2831 |
if (iAlternateSettingList->iTail == NULL) //No more interfaces left
|
sl@0
|
2832 |
break;
|
sl@0
|
2833 |
else
|
sl@0
|
2834 |
{
|
sl@0
|
2835 |
iAlternateSettingList->iTail->iNext = NULL;
|
sl@0
|
2836 |
alternateSettingListRec = iAlternateSettingList->iTail;
|
sl@0
|
2837 |
}
|
sl@0
|
2838 |
}
|
sl@0
|
2839 |
}
|
sl@0
|
2840 |
delete iAlternateSettingList;
|
sl@0
|
2841 |
}
|
sl@0
|
2842 |
|
sl@0
|
2843 |
iNumberOfEndpoints = 0;
|
sl@0
|
2844 |
iAlternateSettingList = NULL;
|
sl@0
|
2845 |
iValidInterface = EFalse;
|
sl@0
|
2846 |
|
sl@0
|
2847 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::DestroyAllInterfaces done"));
|
sl@0
|
2848 |
}
|
sl@0
|
2849 |
|
sl@0
|
2850 |
|
sl@0
|
2851 |
|
sl@0
|
2852 |
|
sl@0
|
2853 |
|
sl@0
|
2854 |
//
|
sl@0
|
2855 |
// DestroyInterface
|
sl@0
|
2856 |
//
|
sl@0
|
2857 |
|
sl@0
|
2858 |
void DLddUsbcScChannel::DestroyInterface(TUint aInterfaceNumber)
|
sl@0
|
2859 |
{
|
sl@0
|
2860 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::DestroyInterface \n"));
|
sl@0
|
2861 |
|
sl@0
|
2862 |
if (iAlternateSetting == aInterfaceNumber)
|
sl@0
|
2863 |
{
|
sl@0
|
2864 |
ResetInterface(KErrUsbInterfaceNotReady);
|
sl@0
|
2865 |
iValidInterface = EFalse;
|
sl@0
|
2866 |
iNumberOfEndpoints = 0;
|
sl@0
|
2867 |
}
|
sl@0
|
2868 |
if (iAlternateSettingList)
|
sl@0
|
2869 |
{
|
sl@0
|
2870 |
TUsbcScAlternateSetting* alternateSettingListRec = iAlternateSettingList->iTail;
|
sl@0
|
2871 |
TUsbcScAlternateSetting* alternateSettingListRecFound = NULL;
|
sl@0
|
2872 |
while (alternateSettingListRec)
|
sl@0
|
2873 |
{
|
sl@0
|
2874 |
if (alternateSettingListRec->iSetting == aInterfaceNumber)
|
sl@0
|
2875 |
{
|
sl@0
|
2876 |
alternateSettingListRecFound = alternateSettingListRec;
|
sl@0
|
2877 |
if (alternateSettingListRec->iPrevious == NULL) //Interface is at HEAD OF List, Should only be if Interface is also at Tail of list
|
sl@0
|
2878 |
{
|
sl@0
|
2879 |
iAlternateSettingList->iHead = alternateSettingListRec->iNext; // Should be NULL
|
sl@0
|
2880 |
if (alternateSettingListRec->iNext)
|
sl@0
|
2881 |
iAlternateSettingList->iHead->iPrevious = NULL;
|
sl@0
|
2882 |
}
|
sl@0
|
2883 |
else if (alternateSettingListRec->iNext == NULL) //Interface is at TAIL OF List
|
sl@0
|
2884 |
{
|
sl@0
|
2885 |
iAlternateSettingList->iTail = alternateSettingListRecFound->iPrevious;
|
sl@0
|
2886 |
iAlternateSettingList->iTail->iNext = NULL;
|
sl@0
|
2887 |
}
|
sl@0
|
2888 |
else //Somewhere in the middle (would not expect this in normal operation, but here for completeness)
|
sl@0
|
2889 |
{
|
sl@0
|
2890 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::DestroyInterface Middle interface!\n"));
|
sl@0
|
2891 |
alternateSettingListRec->iPrevious->iNext = alternateSettingListRec->iNext;
|
sl@0
|
2892 |
alternateSettingListRec->iNext->iPrevious = alternateSettingListRec->iPrevious;
|
sl@0
|
2893 |
}
|
sl@0
|
2894 |
|
sl@0
|
2895 |
delete alternateSettingListRecFound;
|
sl@0
|
2896 |
break;
|
sl@0
|
2897 |
}
|
sl@0
|
2898 |
alternateSettingListRec = alternateSettingListRec->iPrevious;
|
sl@0
|
2899 |
}
|
sl@0
|
2900 |
}
|
sl@0
|
2901 |
}
|
sl@0
|
2902 |
|
sl@0
|
2903 |
//
|
sl@0
|
2904 |
// SetupEp0
|
sl@0
|
2905 |
//
|
sl@0
|
2906 |
|
sl@0
|
2907 |
TInt DLddUsbcScChannel::SetupEp0()
|
sl@0
|
2908 |
{
|
sl@0
|
2909 |
__ASSERT_ALWAYS(iEp0Endpoint==NULL, Kern::Fault("DLddUsbcScChannel::SetupEp0", __LINE__));
|
sl@0
|
2910 |
|
sl@0
|
2911 |
TUsbcScEndpointInfo ep0Info = TUsbcScEndpointInfo(KUsbEpTypeControl, KUsbEpDirBidirect);
|
sl@0
|
2912 |
ep0Info.iSize = iController->Ep0PacketSize();
|
sl@0
|
2913 |
|
sl@0
|
2914 |
TUsbcScEndpoint* ep0 = new TUsbcScEndpoint(this, iController, &ep0Info, 0);
|
sl@0
|
2915 |
if (ep0 == NULL)
|
sl@0
|
2916 |
{
|
sl@0
|
2917 |
return KErrNoMemory;
|
sl@0
|
2918 |
}
|
sl@0
|
2919 |
|
sl@0
|
2920 |
TInt r = ep0->Construct();
|
sl@0
|
2921 |
if (r != KErrNone)
|
sl@0
|
2922 |
{
|
sl@0
|
2923 |
delete ep0;
|
sl@0
|
2924 |
return KErrNoMemory;
|
sl@0
|
2925 |
}
|
sl@0
|
2926 |
|
sl@0
|
2927 |
ep0->SetRealEpNumber(0);
|
sl@0
|
2928 |
ep0->SetBuffer(NULL); // Cannot find it this way.
|
sl@0
|
2929 |
|
sl@0
|
2930 |
iEp0Endpoint = ep0;
|
sl@0
|
2931 |
return KErrNone;
|
sl@0
|
2932 |
}
|
sl@0
|
2933 |
|
sl@0
|
2934 |
//
|
sl@0
|
2935 |
// DestroyEp0
|
sl@0
|
2936 |
//
|
sl@0
|
2937 |
|
sl@0
|
2938 |
void DLddUsbcScChannel::DestroyEp0()
|
sl@0
|
2939 |
{
|
sl@0
|
2940 |
__KTRACE_OPT(KUSB, Kern::Printf(" DLddUsbcScChannel::DestroyEp0"));
|
sl@0
|
2941 |
delete iEp0Endpoint;
|
sl@0
|
2942 |
iEp0Endpoint = NULL;
|
sl@0
|
2943 |
}
|
sl@0
|
2944 |
|
sl@0
|
2945 |
|
sl@0
|
2946 |
void DLddUsbcScChannel::RequestCallbackEp0(TAny* aDLddUsbcScChannel)
|
sl@0
|
2947 |
{
|
sl@0
|
2948 |
DLddUsbcScChannel* channel = (DLddUsbcScChannel*) aDLddUsbcScChannel;
|
sl@0
|
2949 |
|
sl@0
|
2950 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::RequestCallbackEp0"));
|
sl@0
|
2951 |
|
sl@0
|
2952 |
if (channel->ChannelClosing())
|
sl@0
|
2953 |
{
|
sl@0
|
2954 |
__KTRACE_OPT(KUSB, Kern::Printf("Channel Closing: Completion not accepted!"));
|
sl@0
|
2955 |
return;
|
sl@0
|
2956 |
}
|
sl@0
|
2957 |
|
sl@0
|
2958 |
switch (channel->iEp0Endpoint->iRequestCallbackInfo->iTransferDir)
|
sl@0
|
2959 |
{
|
sl@0
|
2960 |
case EControllerWrite:
|
sl@0
|
2961 |
channel->iBuffers[channel->iEP0InBuff].CompleteWrite();
|
sl@0
|
2962 |
return;
|
sl@0
|
2963 |
case EControllerRead:
|
sl@0
|
2964 |
channel->iBuffers[channel->iEP0OutBuff].CompleteRead();
|
sl@0
|
2965 |
return;
|
sl@0
|
2966 |
default:
|
sl@0
|
2967 |
Kern::Printf("DLddUsbcScChannel::RequestCallbackEp0 - Unexpected completion direction %d",channel->iEp0Endpoint->iRequestCallbackInfo->iTransferDir);
|
sl@0
|
2968 |
Kern::Fault("DLddUsbcScChannel::RequestCallbackEp0", __LINE__);
|
sl@0
|
2969 |
}
|
sl@0
|
2970 |
}
|
sl@0
|
2971 |
|
sl@0
|
2972 |
|
sl@0
|
2973 |
|
sl@0
|
2974 |
|
sl@0
|
2975 |
|
sl@0
|
2976 |
|
sl@0
|
2977 |
//
|
sl@0
|
2978 |
// EndpointStatusChangeCallback
|
sl@0
|
2979 |
//
|
sl@0
|
2980 |
|
sl@0
|
2981 |
void DLddUsbcScChannel::EndpointStatusChangeCallback(TAny* aDLddUsbcScChannel)
|
sl@0
|
2982 |
{
|
sl@0
|
2983 |
__KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback"));
|
sl@0
|
2984 |
DLddUsbcScChannel* dUsbc = (DLddUsbcScChannel*) aDLddUsbcScChannel;
|
sl@0
|
2985 |
if (dUsbc->iChannelClosing)
|
sl@0
|
2986 |
return;
|
sl@0
|
2987 |
TUint endpointState = dUsbc->iEndpointStatusCallbackInfo.State();
|
sl@0
|
2988 |
const TInt reqNo = (TInt) RDevUsbcScClient::ERequestEndpointStatusNotify;
|
sl@0
|
2989 |
if (dUsbc->iRequestStatus[reqNo])
|
sl@0
|
2990 |
{
|
sl@0
|
2991 |
__KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback Notify status"));
|
sl@0
|
2992 |
DThread* client = dUsbc->iClient;
|
sl@0
|
2993 |
// set client descriptor length to zero
|
sl@0
|
2994 |
TInt r = Kern::ThreadRawWrite(client, dUsbc->iEndpointStatusChangePtr, &endpointState,
|
sl@0
|
2995 |
sizeof(TUint), client);
|
sl@0
|
2996 |
if (r != KErrNone)
|
sl@0
|
2997 |
dUsbc->PanicClientThread(r);
|
sl@0
|
2998 |
Kern::RequestComplete(dUsbc->iClient, dUsbc->iRequestStatus[reqNo], r);
|
sl@0
|
2999 |
dUsbc->iEndpointStatusChangePtr = NULL;
|
sl@0
|
3000 |
}
|
sl@0
|
3001 |
}
|
sl@0
|
3002 |
|
sl@0
|
3003 |
|
sl@0
|
3004 |
//
|
sl@0
|
3005 |
// StatusChangeCallback
|
sl@0
|
3006 |
//
|
sl@0
|
3007 |
|
sl@0
|
3008 |
void DLddUsbcScChannel::StatusChangeCallback(TAny* aDLddUsbcScChannel)
|
sl@0
|
3009 |
{
|
sl@0
|
3010 |
DLddUsbcScChannel* dUsbc = (DLddUsbcScChannel*) aDLddUsbcScChannel;
|
sl@0
|
3011 |
if (dUsbc->iChannelClosing)
|
sl@0
|
3012 |
return;
|
sl@0
|
3013 |
|
sl@0
|
3014 |
TUsbcDeviceState deviceState;
|
sl@0
|
3015 |
TInt i;
|
sl@0
|
3016 |
for (i = 0;
|
sl@0
|
3017 |
(i < KUsbcDeviceStateRequests) && ((deviceState = dUsbc->iStatusCallbackInfo.State(i)) != EUsbcNoState);
|
sl@0
|
3018 |
++i)
|
sl@0
|
3019 |
{
|
sl@0
|
3020 |
__KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallBack status=%d", deviceState));
|
sl@0
|
3021 |
if (deviceState & KUsbAlternateSetting)
|
sl@0
|
3022 |
{
|
sl@0
|
3023 |
dUsbc->ProcessAlternateSetting(deviceState);
|
sl@0
|
3024 |
}
|
sl@0
|
3025 |
else
|
sl@0
|
3026 |
{
|
sl@0
|
3027 |
dUsbc->ProcessDeviceState(deviceState);
|
sl@0
|
3028 |
// Send Status to EP0 buffer.
|
sl@0
|
3029 |
dUsbc->iBuffers[dUsbc->iEP0OutBuff].SendEp0StatusPacket(deviceState);
|
sl@0
|
3030 |
}
|
sl@0
|
3031 |
|
sl@0
|
3032 |
// Only queue if userside is interested
|
sl@0
|
3033 |
if (dUsbc->iDeviceStatusNeeded)
|
sl@0
|
3034 |
{
|
sl@0
|
3035 |
dUsbc->iStatusFifo->AddStatusToQueue(deviceState);
|
sl@0
|
3036 |
const TInt reqNo = (TInt) RDevUsbcScClient::ERequestAlternateDeviceStatusNotify;
|
sl@0
|
3037 |
if (dUsbc->AlternateDeviceStateTestComplete())
|
sl@0
|
3038 |
Kern::RequestComplete(dUsbc->iClient, dUsbc->iRequestStatus[reqNo], KErrNone);
|
sl@0
|
3039 |
}
|
sl@0
|
3040 |
}
|
sl@0
|
3041 |
// We don't want to be interrupted in the middle of this:
|
sl@0
|
3042 |
const TInt irqs = NKern::DisableInterrupts(2);
|
sl@0
|
3043 |
dUsbc->iStatusCallbackInfo.ResetState();
|
sl@0
|
3044 |
NKern::RestoreInterrupts(irqs);
|
sl@0
|
3045 |
}
|
sl@0
|
3046 |
|
sl@0
|
3047 |
|
sl@0
|
3048 |
void DLddUsbcScChannel::OtgFeatureChangeCallback(TAny* aDLddUsbcScChannel)
|
sl@0
|
3049 |
{
|
sl@0
|
3050 |
__KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback"));
|
sl@0
|
3051 |
DLddUsbcScChannel* dUsbc = (DLddUsbcScChannel*) aDLddUsbcScChannel;
|
sl@0
|
3052 |
if (dUsbc->iChannelClosing)
|
sl@0
|
3053 |
return;
|
sl@0
|
3054 |
|
sl@0
|
3055 |
TUint8 features;
|
sl@0
|
3056 |
// No return value check. Assume OTG always supported here
|
sl@0
|
3057 |
dUsbc->iController->GetCurrentOtgFeatures(features);
|
sl@0
|
3058 |
|
sl@0
|
3059 |
const TInt reqNo = (TInt) RDevUsbcScClient::ERequestOtgFeaturesNotify;
|
sl@0
|
3060 |
if (dUsbc->iRequestStatus[reqNo])
|
sl@0
|
3061 |
{
|
sl@0
|
3062 |
__KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback Notify status"));
|
sl@0
|
3063 |
TInt r = Kern::ThreadRawWrite(dUsbc->iClient, dUsbc->iOtgFeatureChangePtr,
|
sl@0
|
3064 |
&features, sizeof(TUint8), dUsbc->iClient);
|
sl@0
|
3065 |
if (r != KErrNone)
|
sl@0
|
3066 |
dUsbc->PanicClientThread(r);
|
sl@0
|
3067 |
Kern::RequestComplete(dUsbc->iClient, dUsbc->iRequestStatus[reqNo], r);
|
sl@0
|
3068 |
dUsbc->iOtgFeatureChangePtr = NULL;
|
sl@0
|
3069 |
}
|
sl@0
|
3070 |
}
|
sl@0
|
3071 |
|
sl@0
|
3072 |
|
sl@0
|
3073 |
//
|
sl@0
|
3074 |
// SelectAlternateSetting
|
sl@0
|
3075 |
//
|
sl@0
|
3076 |
|
sl@0
|
3077 |
TInt DLddUsbcScChannel::SelectAlternateSetting(TUint aAlternateSetting)
|
sl@0
|
3078 |
{
|
sl@0
|
3079 |
TUsbcScEndpoint* ep;
|
sl@0
|
3080 |
|
sl@0
|
3081 |
// First, find the alt setting record, which corresponds to the alt setting number.
|
sl@0
|
3082 |
TUsbcScAlternateSetting* alternateSettingListRec;
|
sl@0
|
3083 |
if(iAlternateSettingList)
|
sl@0
|
3084 |
{
|
sl@0
|
3085 |
for (alternateSettingListRec = iAlternateSettingList->iHead; alternateSettingListRec; alternateSettingListRec = alternateSettingListRec->iNext)
|
sl@0
|
3086 |
if (alternateSettingListRec->iSetting == aAlternateSetting)
|
sl@0
|
3087 |
{
|
sl@0
|
3088 |
// Record has been located.
|
sl@0
|
3089 |
|
sl@0
|
3090 |
// Update current ep setting vars
|
sl@0
|
3091 |
iEndpoint = alternateSettingListRec->iEndpoint;
|
sl@0
|
3092 |
iNumberOfEndpoints = alternateSettingListRec->iNumberOfEndpoints;
|
sl@0
|
3093 |
|
sl@0
|
3094 |
|
sl@0
|
3095 |
|
sl@0
|
3096 |
// Reset buffers for new ep set
|
sl@0
|
3097 |
for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
|
sl@0
|
3098 |
{
|
sl@0
|
3099 |
ep = alternateSettingListRec->iEndpoint[i];
|
sl@0
|
3100 |
if (ep!=NULL)
|
sl@0
|
3101 |
ep->StartBuffer(); // Buffer::StartEndpoint(...) sets the necessary parameters to the buffer, for use for a perticular endpoint.
|
sl@0
|
3102 |
}
|
sl@0
|
3103 |
|
sl@0
|
3104 |
return KErrNone;
|
sl@0
|
3105 |
}
|
sl@0
|
3106 |
}
|
sl@0
|
3107 |
return KErrGeneral;
|
sl@0
|
3108 |
}
|
sl@0
|
3109 |
|
sl@0
|
3110 |
/* The user calls this to move into the next alternate setting. After this call, it is assumed the user wants to
|
sl@0
|
3111 |
Transmit using endpoints belonging to this alternate Setting. Writes to the IN endpoints will be allowed until
|
sl@0
|
3112 |
the host changed the alternate setting again
|
sl@0
|
3113 |
Returns a 32 int with the top 16 bits represents the sequance, and the botten, the alternatre setting no.
|
sl@0
|
3114 |
*/
|
sl@0
|
3115 |
TInt32 DLddUsbcScChannel::StartNextInAlternateSetting()
|
sl@0
|
3116 |
{
|
sl@0
|
3117 |
iUserKnowsAltSetting = ETrue;
|
sl@0
|
3118 |
return iAsSeq<<16 | iAlternateSetting;
|
sl@0
|
3119 |
}
|
sl@0
|
3120 |
|
sl@0
|
3121 |
|
sl@0
|
3122 |
//
|
sl@0
|
3123 |
// EpFromAlternateSetting
|
sl@0
|
3124 |
//
|
sl@0
|
3125 |
|
sl@0
|
3126 |
TInt DLddUsbcScChannel::EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint)
|
sl@0
|
3127 |
{
|
sl@0
|
3128 |
TUsbcScAlternateSetting* alternateSettingListRec = iAlternateSettingList->iHead;
|
sl@0
|
3129 |
while (alternateSettingListRec)
|
sl@0
|
3130 |
{
|
sl@0
|
3131 |
if (alternateSettingListRec->iSetting == aAlternateSetting)
|
sl@0
|
3132 |
{
|
sl@0
|
3133 |
if ((aEndpoint <= alternateSettingListRec->iNumberOfEndpoints) &&
|
sl@0
|
3134 |
(aEndpoint > 0))
|
sl@0
|
3135 |
{
|
sl@0
|
3136 |
return alternateSettingListRec->iEndpoint[aEndpoint]->RealEpNumber();
|
sl@0
|
3137 |
}
|
sl@0
|
3138 |
else
|
sl@0
|
3139 |
{
|
sl@0
|
3140 |
__KTRACE_OPT(KPANIC, Kern::Printf(" Error: aEndpoint %d wrong for aAlternateSetting %d",
|
sl@0
|
3141 |
aEndpoint, aAlternateSetting));
|
sl@0
|
3142 |
return KErrNotFound;
|
sl@0
|
3143 |
}
|
sl@0
|
3144 |
}
|
sl@0
|
3145 |
alternateSettingListRec = alternateSettingListRec->iNext;
|
sl@0
|
3146 |
}
|
sl@0
|
3147 |
__KTRACE_OPT(KPANIC, Kern::Printf(" Error: no aAlternateSetting %d found", aAlternateSetting));
|
sl@0
|
3148 |
return KErrNotFound;
|
sl@0
|
3149 |
}
|
sl@0
|
3150 |
|
sl@0
|
3151 |
//
|
sl@0
|
3152 |
// ProcessAlternateSetting
|
sl@0
|
3153 |
//
|
sl@0
|
3154 |
|
sl@0
|
3155 |
TInt DLddUsbcScChannel::ProcessAlternateSetting(TUint aAlternateSetting)
|
sl@0
|
3156 |
{
|
sl@0
|
3157 |
|
sl@0
|
3158 |
TUint newSetting = aAlternateSetting&(~KUsbAlternateSetting);
|
sl@0
|
3159 |
__KTRACE_OPT(KUSB, Kern::Printf("ProcessAlternateSetting 0x%08x selecting alternate setting 0x%08x", aAlternateSetting, newSetting));
|
sl@0
|
3160 |
iUserKnowsAltSetting=EFalse;
|
sl@0
|
3161 |
iAlternateSetting = newSetting;
|
sl@0
|
3162 |
iAsSeq++;
|
sl@0
|
3163 |
|
sl@0
|
3164 |
ResetInterface(KErrUsbInterfaceChange); // kill any outstanding IN transfers
|
sl@0
|
3165 |
|
sl@0
|
3166 |
TInt r = SelectAlternateSetting(newSetting);
|
sl@0
|
3167 |
if (r != KErrNone)
|
sl@0
|
3168 |
return r;
|
sl@0
|
3169 |
|
sl@0
|
3170 |
|
sl@0
|
3171 |
StartEpReads();
|
sl@0
|
3172 |
return KErrNone;
|
sl@0
|
3173 |
}
|
sl@0
|
3174 |
|
sl@0
|
3175 |
|
sl@0
|
3176 |
//
|
sl@0
|
3177 |
// ProcessDeviceState
|
sl@0
|
3178 |
//
|
sl@0
|
3179 |
// Called from StatusChangeCallback.
|
sl@0
|
3180 |
|
sl@0
|
3181 |
TInt DLddUsbcScChannel::ProcessDeviceState(TUsbcDeviceState aDeviceState)
|
sl@0
|
3182 |
{
|
sl@0
|
3183 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::ProcessDeviceState(%d -> %d)", iDeviceState, aDeviceState));
|
sl@0
|
3184 |
if (iDeviceState == aDeviceState)
|
sl@0
|
3185 |
{
|
sl@0
|
3186 |
__KTRACE_OPT(KUSB, Kern::Printf(" No state change => nothing to be done."));
|
sl@0
|
3187 |
return KErrNone;
|
sl@0
|
3188 |
}
|
sl@0
|
3189 |
if (iDeviceState == EUsbcDeviceStateSuspended)
|
sl@0
|
3190 |
{
|
sl@0
|
3191 |
__KTRACE_OPT(KUSB, Kern::Printf(" Coming out of Suspend: old state = %d", iOldDeviceState));
|
sl@0
|
3192 |
iDeviceState = iOldDeviceState;
|
sl@0
|
3193 |
if (iDeviceState == aDeviceState)
|
sl@0
|
3194 |
{
|
sl@0
|
3195 |
__KTRACE_OPT(KUSB, Kern::Printf(" New state same as before Suspend => nothing to be done."));
|
sl@0
|
3196 |
return KErrNone;
|
sl@0
|
3197 |
}
|
sl@0
|
3198 |
}
|
sl@0
|
3199 |
TBool renumerateState = (aDeviceState == EUsbcDeviceStateConfigured);
|
sl@0
|
3200 |
TBool deconfigured = EFalse;
|
sl@0
|
3201 |
TInt cancellationCode = KErrNone;
|
sl@0
|
3202 |
if (aDeviceState == EUsbcDeviceStateSuspended)
|
sl@0
|
3203 |
{
|
sl@0
|
3204 |
__KTRACE_OPT(KUSB, Kern::Printf(" Suspending..."));
|
sl@0
|
3205 |
iOldDeviceState = iDeviceState;
|
sl@0
|
3206 |
// Put PSL into low power mode here
|
sl@0
|
3207 |
}
|
sl@0
|
3208 |
else
|
sl@0
|
3209 |
{
|
sl@0
|
3210 |
deconfigured = (iDeviceState == EUsbcDeviceStateConfigured &&
|
sl@0
|
3211 |
aDeviceState != EUsbcDeviceStateConfigured);
|
sl@0
|
3212 |
if (iDeviceState == EUsbcDeviceStateConfigured)
|
sl@0
|
3213 |
{
|
sl@0
|
3214 |
if (aDeviceState == EUsbcDeviceStateUndefined)
|
sl@0
|
3215 |
cancellationCode = KErrUsbCableDetached;
|
sl@0
|
3216 |
else if (aDeviceState == EUsbcDeviceStateAddress)
|
sl@0
|
3217 |
cancellationCode = KErrUsbDeviceNotConfigured;
|
sl@0
|
3218 |
else if (aDeviceState == EUsbcDeviceStateDefault)
|
sl@0
|
3219 |
cancellationCode = KErrUsbDeviceBusReset;
|
sl@0
|
3220 |
else
|
sl@0
|
3221 |
cancellationCode = KErrUsbDeviceNotConfigured;
|
sl@0
|
3222 |
}
|
sl@0
|
3223 |
}
|
sl@0
|
3224 |
iDeviceState = aDeviceState;
|
sl@0
|
3225 |
if (iValidInterface || iOwnsDeviceControl)
|
sl@0
|
3226 |
{
|
sl@0
|
3227 |
|
sl@0
|
3228 |
// This LDD may not own an interface. It could be some manager reenumerating
|
sl@0
|
3229 |
// after its subordinate LDDs have setup their interfaces.
|
sl@0
|
3230 |
if (deconfigured)
|
sl@0
|
3231 |
{
|
sl@0
|
3232 |
DeConfigure(cancellationCode);
|
sl@0
|
3233 |
}
|
sl@0
|
3234 |
else if (renumerateState)
|
sl@0
|
3235 |
{
|
sl@0
|
3236 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScChannel:: Reumerated!"));
|
sl@0
|
3237 |
// Select main interface & latch in new endpoint set
|
sl@0
|
3238 |
SelectAlternateSetting(0);
|
sl@0
|
3239 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScChannel:: StartReads!"));
|
sl@0
|
3240 |
StartEpReads();
|
sl@0
|
3241 |
}
|
sl@0
|
3242 |
}
|
sl@0
|
3243 |
|
sl@0
|
3244 |
const TInt reqNo = (TInt) RDevUsbcScClient::ERequestReEnumerate;
|
sl@0
|
3245 |
if (renumerateState && iRequestStatus[reqNo])
|
sl@0
|
3246 |
{
|
sl@0
|
3247 |
// This lot must be done if we are reenumerated
|
sl@0
|
3248 |
Kern::RequestComplete(iClient, iRequestStatus[reqNo], KErrNone);
|
sl@0
|
3249 |
}
|
sl@0
|
3250 |
|
sl@0
|
3251 |
return KErrNone;
|
sl@0
|
3252 |
}
|
sl@0
|
3253 |
|
sl@0
|
3254 |
|
sl@0
|
3255 |
TBool DLddUsbcScChannel::AlternateDeviceStateTestComplete()
|
sl@0
|
3256 |
{
|
sl@0
|
3257 |
TBool completeNow = EFalse;
|
sl@0
|
3258 |
const TInt reqNo = (TInt) RDevUsbcScClient::ERequestAlternateDeviceStatusNotify;
|
sl@0
|
3259 |
if (iRequestStatus[reqNo])
|
sl@0
|
3260 |
{
|
sl@0
|
3261 |
// User req is outstanding
|
sl@0
|
3262 |
TUint32 deviceState;
|
sl@0
|
3263 |
if (iStatusFifo->GetDeviceQueuedStatus(deviceState) == KErrNone)
|
sl@0
|
3264 |
{
|
sl@0
|
3265 |
// Device state waiting to be sent userside
|
sl@0
|
3266 |
completeNow = ETrue;
|
sl@0
|
3267 |
__KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallback Notify status"));
|
sl@0
|
3268 |
// set client descriptor length to zero
|
sl@0
|
3269 |
TInt r = Kern::ThreadRawWrite(iClient, iStatusChangePtr, &deviceState,
|
sl@0
|
3270 |
sizeof(TUint32), iClient);
|
sl@0
|
3271 |
if (r != KErrNone)
|
sl@0
|
3272 |
PanicClientThread(r);
|
sl@0
|
3273 |
iStatusChangePtr = NULL;
|
sl@0
|
3274 |
}
|
sl@0
|
3275 |
}
|
sl@0
|
3276 |
return completeNow;
|
sl@0
|
3277 |
}
|
sl@0
|
3278 |
|
sl@0
|
3279 |
|
sl@0
|
3280 |
void DLddUsbcScChannel::DeConfigure(TInt aErrorCode)
|
sl@0
|
3281 |
{
|
sl@0
|
3282 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::DeConfigure()"));
|
sl@0
|
3283 |
// Called after deconfiguration. Cancels transfers on all endpoints.
|
sl@0
|
3284 |
ResetInterface(aErrorCode);
|
sl@0
|
3285 |
// Cancel the endpoint status notify request if it is outstanding.
|
sl@0
|
3286 |
const TInt KEpNotReq = RDevUsbcScClient::ERequestEndpointStatusNotify;
|
sl@0
|
3287 |
if (iRequestStatus[KEpNotReq])
|
sl@0
|
3288 |
{
|
sl@0
|
3289 |
CancelNotifyEndpointStatus();
|
sl@0
|
3290 |
Kern::RequestComplete(iClient, iRequestStatus[KEpNotReq], aErrorCode);
|
sl@0
|
3291 |
}
|
sl@0
|
3292 |
// We have to reset the alternate setting number when the config goes away.
|
sl@0
|
3293 |
SelectAlternateSetting(0);
|
sl@0
|
3294 |
iAlternateSetting = 0;
|
sl@0
|
3295 |
}
|
sl@0
|
3296 |
|
sl@0
|
3297 |
|
sl@0
|
3298 |
void DLddUsbcScChannel::StartEpReads()
|
sl@0
|
3299 |
{
|
sl@0
|
3300 |
// Queued after enumeration. Starts reads on all endpoints.
|
sl@0
|
3301 |
// The endpoint itself decides if it can do a read
|
sl@0
|
3302 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::StartEpReads - 1"));
|
sl@0
|
3303 |
|
sl@0
|
3304 |
TInt i;
|
sl@0
|
3305 |
TInt8 needsPacket;
|
sl@0
|
3306 |
|
sl@0
|
3307 |
for (i=0; i<iNumBuffers; i++)
|
sl@0
|
3308 |
{
|
sl@0
|
3309 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::StartEpReads - 2 %d",i));
|
sl@0
|
3310 |
|
sl@0
|
3311 |
needsPacket = iBuffers[i].iNeedsPacket;
|
sl@0
|
3312 |
if (needsPacket)
|
sl@0
|
3313 |
{
|
sl@0
|
3314 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::StartEpReads - 3"));
|
sl@0
|
3315 |
iBuffers[i].UpdateBufferList(0,0,(needsPacket==TUsbcScBuffer::KEpIsStarting));
|
sl@0
|
3316 |
}
|
sl@0
|
3317 |
}
|
sl@0
|
3318 |
|
sl@0
|
3319 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::StartEpReads - 4"));
|
sl@0
|
3320 |
|
sl@0
|
3321 |
// now update ep0
|
sl@0
|
3322 |
iBuffers[iEP0OutBuff].Ep0CancelLddRead();
|
sl@0
|
3323 |
iBuffers[iEP0OutBuff].UpdateBufferList(0,0);
|
sl@0
|
3324 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::StartEpReads - 5"));
|
sl@0
|
3325 |
|
sl@0
|
3326 |
}
|
sl@0
|
3327 |
|
sl@0
|
3328 |
|
sl@0
|
3329 |
void DLddUsbcScChannel::ResetInterface(TInt aErrorCode)
|
sl@0
|
3330 |
{
|
sl@0
|
3331 |
if (!iValidInterface && !iOwnsDeviceControl)
|
sl@0
|
3332 |
return;
|
sl@0
|
3333 |
|
sl@0
|
3334 |
TInt i;
|
sl@0
|
3335 |
for (i=0; i<iNumBuffers; i++)
|
sl@0
|
3336 |
{
|
sl@0
|
3337 |
iBuffers[i].iNeedsPacket=TUsbcScBuffer::KNoEpAssigned;
|
sl@0
|
3338 |
}
|
sl@0
|
3339 |
|
sl@0
|
3340 |
TUsbcScBuffer* buffer;
|
sl@0
|
3341 |
|
sl@0
|
3342 |
for (i = 1; i <= iNumberOfEndpoints; i++)
|
sl@0
|
3343 |
{
|
sl@0
|
3344 |
// Firstly, cancel ('garbge collect') any stale reads/writes into PIL.
|
sl@0
|
3345 |
|
sl@0
|
3346 |
__KTRACE_OPT(KUSB, Kern::Printf("Cancelling transfer ep=%d", i));
|
sl@0
|
3347 |
iEndpoint[i]->AbortTransfer();
|
sl@0
|
3348 |
|
sl@0
|
3349 |
// All OUT endpoints need a packet sent, to indicate the termination of the current ep 'pipe'.
|
sl@0
|
3350 |
// This will complete any current read, or will be read later.
|
sl@0
|
3351 |
// All IN endpoints must be simply cancelled, including anything queued.
|
sl@0
|
3352 |
// Ep0 operates outside alt settings, and so we don't cancel anything.
|
sl@0
|
3353 |
|
sl@0
|
3354 |
buffer=iEndpoint[i]->GetBuffer();
|
sl@0
|
3355 |
if (buffer->iDirection==KUsbcScIn)
|
sl@0
|
3356 |
{
|
sl@0
|
3357 |
buffer->iStatusList.Complete(KErrCancel); //aErrorCode
|
sl@0
|
3358 |
buffer->iStatusList.CancelQueued(); //aErrorCode
|
sl@0
|
3359 |
}
|
sl@0
|
3360 |
else
|
sl@0
|
3361 |
buffer->iNeedsPacket=TUsbcScBuffer::KEpIsEnding; // We will send a packet on re-start, which doubles as a 'cancel'
|
sl@0
|
3362 |
// for the old alt setting.
|
sl@0
|
3363 |
}
|
sl@0
|
3364 |
}
|
sl@0
|
3365 |
|
sl@0
|
3366 |
|
sl@0
|
3367 |
|
sl@0
|
3368 |
void DLddUsbcScChannel::EmergencyCompleteDfc(TAny* aDLddUsbcScChannel)
|
sl@0
|
3369 |
{
|
sl@0
|
3370 |
((DLddUsbcScChannel*) aDLddUsbcScChannel)->DoEmergencyComplete();
|
sl@0
|
3371 |
}
|
sl@0
|
3372 |
|
sl@0
|
3373 |
TInt DLddUsbcScChannel::DoEmergencyComplete()
|
sl@0
|
3374 |
{
|
sl@0
|
3375 |
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::DoEmergencyComplete"));
|
sl@0
|
3376 |
// cancel any pending DFCs
|
sl@0
|
3377 |
// complete all client requests
|
sl@0
|
3378 |
|
sl@0
|
3379 |
TUsbcScBuffer* buffer;
|
sl@0
|
3380 |
TInt i;
|
sl@0
|
3381 |
// Complete EP0 request
|
sl@0
|
3382 |
|
sl@0
|
3383 |
TInt direction=iEp0Endpoint->iRequestCallbackInfo->iTransferDir;
|
sl@0
|
3384 |
if (direction==EControllerWrite)
|
sl@0
|
3385 |
{
|
sl@0
|
3386 |
iBuffers[iEP0InBuff].iStatusList.CancelQueued();
|
sl@0
|
3387 |
iBuffers[iEP0InBuff].iStatusList.Complete(KErrDisconnected);
|
sl@0
|
3388 |
}
|
sl@0
|
3389 |
else if (direction==EControllerRead)
|
sl@0
|
3390 |
{
|
sl@0
|
3391 |
iBuffers[iEP0OutBuff].iStatusList.CancelQueued();
|
sl@0
|
3392 |
iBuffers[iEP0OutBuff].iStatusList.Complete(KErrDisconnected);
|
sl@0
|
3393 |
}
|
sl@0
|
3394 |
|
sl@0
|
3395 |
// Complete other Eps request
|
sl@0
|
3396 |
for (i = 1; i <= iNumberOfEndpoints; i++)
|
sl@0
|
3397 |
{
|
sl@0
|
3398 |
__KTRACE_OPT(KUSB, Kern::Printf("Cancelling transfer ep=%d", i));
|
sl@0
|
3399 |
buffer=iEndpoint[i]->GetBuffer();
|
sl@0
|
3400 |
buffer->iStatusList.CancelQueued();
|
sl@0
|
3401 |
buffer->iStatusList.Complete(KErrDisconnected);
|
sl@0
|
3402 |
}
|
sl@0
|
3403 |
|
sl@0
|
3404 |
// Complete remaining requests
|
sl@0
|
3405 |
|
sl@0
|
3406 |
for (TInt i = 0; i < KUsbcMaxRequests; i++)
|
sl@0
|
3407 |
{
|
sl@0
|
3408 |
if (iRequestStatus[i])
|
sl@0
|
3409 |
{
|
sl@0
|
3410 |
__KTRACE_OPT(KUSB, Kern::Printf("Complete request 0x%x", iRequestStatus[i]));
|
sl@0
|
3411 |
Kern::RequestComplete(iClient, iRequestStatus[i], KErrDisconnected);
|
sl@0
|
3412 |
}
|
sl@0
|
3413 |
}
|
sl@0
|
3414 |
iStatusCallbackInfo.Cancel();
|
sl@0
|
3415 |
iEndpointStatusCallbackInfo.Cancel();
|
sl@0
|
3416 |
iOtgFeatureCallbackInfo.Cancel();
|
sl@0
|
3417 |
|
sl@0
|
3418 |
return KErrNone;
|
sl@0
|
3419 |
}
|
sl@0
|
3420 |
|
sl@0
|
3421 |
|
sl@0
|
3422 |
void DLddUsbcScChannel::PanicClientThread(TInt aReason)
|
sl@0
|
3423 |
{
|
sl@0
|
3424 |
Kern::ThreadKill(iClient, EExitPanic, aReason, KUsbLDDKillCat);
|
sl@0
|
3425 |
}
|
sl@0
|
3426 |
|
sl@0
|
3427 |
// End DLddUsbcScChannel
|
sl@0
|
3428 |
|
sl@0
|
3429 |
/*****************************************************************************\
|
sl@0
|
3430 |
* TUsbcScEndpoint *
|
sl@0
|
3431 |
* *
|
sl@0
|
3432 |
* *
|
sl@0
|
3433 |
* *
|
sl@0
|
3434 |
\*****************************************************************************/
|
sl@0
|
3435 |
|
sl@0
|
3436 |
|
sl@0
|
3437 |
// Constructor
|
sl@0
|
3438 |
TUsbcScEndpoint::TUsbcScEndpoint(DLddUsbcScChannel* aLDD, DUsbClientController* aController,
|
sl@0
|
3439 |
const TUsbcScEndpointInfo* aEndpointInfo, TInt aEndpointNum
|
sl@0
|
3440 |
)
|
sl@0
|
3441 |
: iRequestCallbackInfo(NULL),
|
sl@0
|
3442 |
iController(aController),
|
sl@0
|
3443 |
iEndpointInfo(*aEndpointInfo),
|
sl@0
|
3444 |
iClientReadPending(EFalse),
|
sl@0
|
3445 |
iClientWritePending(EFalse),
|
sl@0
|
3446 |
iEndpointNumber(aEndpointNum),
|
sl@0
|
3447 |
iRealEpNumber(-1),
|
sl@0
|
3448 |
iLdd(aLDD),
|
sl@0
|
3449 |
iError(KErrNone),
|
sl@0
|
3450 |
iBytesTransferred(0),
|
sl@0
|
3451 |
iBuffer(NULL)
|
sl@0
|
3452 |
{
|
sl@0
|
3453 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScEndpoint::TUsbcScEndpoint"));
|
sl@0
|
3454 |
}
|
sl@0
|
3455 |
|
sl@0
|
3456 |
|
sl@0
|
3457 |
TInt TUsbcScEndpoint::Construct()
|
sl@0
|
3458 |
{
|
sl@0
|
3459 |
__KTRACE_OPT(KUSB,Kern::Printf("TUsbcScEndpoint::TUsbcScEndpoint iEndpointNumber %d\n",iEndpointNumber));
|
sl@0
|
3460 |
|
sl@0
|
3461 |
iRequestCallbackInfo = new TUsbcRequestCallback(iLdd,
|
sl@0
|
3462 |
iEndpointNumber,
|
sl@0
|
3463 |
(iEndpointNumber==0)?DLddUsbcScChannel::RequestCallbackEp0:TUsbcScEndpoint::RequestCallback,
|
sl@0
|
3464 |
(iEndpointNumber==0)? (TAny*) iLdd: (TAny*) this,
|
sl@0
|
3465 |
iLdd->iDfcQ,
|
sl@0
|
3466 |
KUsbRequestCallbackPriority);
|
sl@0
|
3467 |
|
sl@0
|
3468 |
return (iRequestCallbackInfo == NULL)?KErrNoMemory:KErrNone;
|
sl@0
|
3469 |
}
|
sl@0
|
3470 |
|
sl@0
|
3471 |
|
sl@0
|
3472 |
TUsbcScEndpoint::~TUsbcScEndpoint()
|
sl@0
|
3473 |
{
|
sl@0
|
3474 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScEndpoint::~TUsbcScEndpoint(%d)", iEndpointNumber));
|
sl@0
|
3475 |
AbortTransfer();
|
sl@0
|
3476 |
delete iRequestCallbackInfo;
|
sl@0
|
3477 |
}
|
sl@0
|
3478 |
|
sl@0
|
3479 |
// This is called by the PIL, on return from a read or write.
|
sl@0
|
3480 |
// Inturn it calls either the read or write function for that buffer.
|
sl@0
|
3481 |
|
sl@0
|
3482 |
void TUsbcScEndpoint::RequestCallback(TAny* aTUsbcScEndpoint)
|
sl@0
|
3483 |
{
|
sl@0
|
3484 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScEndpoint::RequestCallback"));
|
sl@0
|
3485 |
|
sl@0
|
3486 |
if (((TUsbcScEndpoint*)aTUsbcScEndpoint)->iLdd->ChannelClosing())
|
sl@0
|
3487 |
{
|
sl@0
|
3488 |
__KTRACE_OPT(KUSB, Kern::Printf("Channel Closing: Completion not accepted!"));
|
sl@0
|
3489 |
return;
|
sl@0
|
3490 |
}
|
sl@0
|
3491 |
|
sl@0
|
3492 |
switch (((TUsbcScEndpoint*) aTUsbcScEndpoint)->iRequestCallbackInfo->iTransferDir)
|
sl@0
|
3493 |
{
|
sl@0
|
3494 |
case EControllerWrite:
|
sl@0
|
3495 |
((TUsbcScEndpoint*) aTUsbcScEndpoint)->iBuffer->CompleteWrite();
|
sl@0
|
3496 |
return;
|
sl@0
|
3497 |
case EControllerRead:
|
sl@0
|
3498 |
((TUsbcScEndpoint*) aTUsbcScEndpoint)->iBuffer->CompleteRead();
|
sl@0
|
3499 |
return;
|
sl@0
|
3500 |
default:
|
sl@0
|
3501 |
Kern::Printf("TUsbcScEndpoint::RequestCallback - Unexpected compleation direction %d",((TUsbcScEndpoint*) aTUsbcScEndpoint)->iRequestCallbackInfo->iTransferDir);
|
sl@0
|
3502 |
Kern::Fault("TUsbcScEndpoint::RequestCallback", __LINE__);
|
sl@0
|
3503 |
}
|
sl@0
|
3504 |
}
|
sl@0
|
3505 |
|
sl@0
|
3506 |
|
sl@0
|
3507 |
/*
|
sl@0
|
3508 |
|
sl@0
|
3509 |
This is used to tidy up cancel calls into the PIL, regardless of them being reads or writes
|
sl@0
|
3510 |
|
sl@0
|
3511 |
*/
|
sl@0
|
3512 |
|
sl@0
|
3513 |
void TUsbcScEndpoint::AbortTransfer()
|
sl@0
|
3514 |
{
|
sl@0
|
3515 |
if (!iLdd->iRealizeCalled)
|
sl@0
|
3516 |
{
|
sl@0
|
3517 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScEndpoint::AbortTransfer Ep# %d Real Ep # %d - N.R.",iEndpointNumber, iRealEpNumber));
|
sl@0
|
3518 |
return;
|
sl@0
|
3519 |
}
|
sl@0
|
3520 |
else
|
sl@0
|
3521 |
{
|
sl@0
|
3522 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScEndpoint::AbortTransfer Ep# %d Real Ep # %d",iEndpointNumber, iRealEpNumber));
|
sl@0
|
3523 |
}
|
sl@0
|
3524 |
|
sl@0
|
3525 |
|
sl@0
|
3526 |
if (iBuffer && (iBuffer->iStatusList.iState) || (!iRealEpNumber))
|
sl@0
|
3527 |
{
|
sl@0
|
3528 |
if (iRequestCallbackInfo->iTransferDir==EControllerWrite)
|
sl@0
|
3529 |
iController->CancelWriteBuffer(iLdd, iRealEpNumber);
|
sl@0
|
3530 |
else if (iRequestCallbackInfo->iTransferDir==EControllerRead)
|
sl@0
|
3531 |
iController->CancelReadBuffer(iLdd, iRealEpNumber);
|
sl@0
|
3532 |
else
|
sl@0
|
3533 |
{
|
sl@0
|
3534 |
if (iEndpointNumber!=0) // endpoint zero starts off not sent in any direction, then keeps changing.
|
sl@0
|
3535 |
{
|
sl@0
|
3536 |
__KTRACE_OPT(KUSB,Kern::Printf("\nTUsbcScEndpoint::AbortTransfer WARNING: Invalid Direction %d on (%d,%d)!\n",iRequestCallbackInfo->iTransferDir,iEndpointNumber, iRealEpNumber));
|
sl@0
|
3537 |
}
|
sl@0
|
3538 |
else
|
sl@0
|
3539 |
{
|
sl@0
|
3540 |
__KTRACE_OPT(KUSB, Kern::Printf("\nTUsbcScEndpoint::AbortTransfer Can't stop direction %d on (%d,%d)!\n",iRequestCallbackInfo->iTransferDir,iEndpointNumber, iRealEpNumber));
|
sl@0
|
3541 |
}
|
sl@0
|
3542 |
}
|
sl@0
|
3543 |
}
|
sl@0
|
3544 |
else if (!iBuffer)
|
sl@0
|
3545 |
{
|
sl@0
|
3546 |
__KTRACE_OPT(KUSB,Kern::Printf("\nTUsbcScEndpoint::AbortTransfer WARNING: iBuffer is NULL on (%d,%d)\n",iEndpointNumber, iRealEpNumber));
|
sl@0
|
3547 |
return;
|
sl@0
|
3548 |
}
|
sl@0
|
3549 |
|
sl@0
|
3550 |
if (iRequestCallbackInfo)
|
sl@0
|
3551 |
iRequestCallbackInfo->iDfc.Cancel();
|
sl@0
|
3552 |
else
|
sl@0
|
3553 |
{
|
sl@0
|
3554 |
__KTRACE_OPT(KUSB,Kern::Printf("\nTUsbcScEndpoint::AbortTransfer WARNING: iRequestCallbackInfo is NULL\n"));
|
sl@0
|
3555 |
}
|
sl@0
|
3556 |
|
sl@0
|
3557 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScEndpoint Done."));
|
sl@0
|
3558 |
}
|
sl@0
|
3559 |
|
sl@0
|
3560 |
// End TUsbcScEndpoint
|
sl@0
|
3561 |
|
sl@0
|
3562 |
|
sl@0
|
3563 |
/*****************************************************************************\
|
sl@0
|
3564 |
* TUsbcScAlternateSettingList *
|
sl@0
|
3565 |
* *
|
sl@0
|
3566 |
* *
|
sl@0
|
3567 |
* *
|
sl@0
|
3568 |
\*****************************************************************************/
|
sl@0
|
3569 |
|
sl@0
|
3570 |
|
sl@0
|
3571 |
TUsbcScAlternateSetting::TUsbcScAlternateSetting()
|
sl@0
|
3572 |
: iNext(NULL),
|
sl@0
|
3573 |
iPrevious(NULL),
|
sl@0
|
3574 |
iNumberOfEndpoints(0),
|
sl@0
|
3575 |
iSetting(0)
|
sl@0
|
3576 |
{
|
sl@0
|
3577 |
for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
|
sl@0
|
3578 |
{
|
sl@0
|
3579 |
iEndpoint[i] = NULL;
|
sl@0
|
3580 |
}
|
sl@0
|
3581 |
}
|
sl@0
|
3582 |
|
sl@0
|
3583 |
|
sl@0
|
3584 |
TUsbcScAlternateSetting::~TUsbcScAlternateSetting()
|
sl@0
|
3585 |
{
|
sl@0
|
3586 |
__KTRACE_OPT(KUSB, Kern::Printf("TUsbcScAlternateSetting::~TUsbcScAlternateSetting()"));
|
sl@0
|
3587 |
for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
|
sl@0
|
3588 |
{
|
sl@0
|
3589 |
delete iEndpoint[i];
|
sl@0
|
3590 |
}
|
sl@0
|
3591 |
}
|
sl@0
|
3592 |
|
sl@0
|
3593 |
// End TUsbcScAlternateSettingList
|
sl@0
|
3594 |
|
sl@0
|
3595 |
|
sl@0
|
3596 |
|
sl@0
|
3597 |
TUsbcScAlternateSettingList::TUsbcScAlternateSettingList()
|
sl@0
|
3598 |
: iHead(NULL),
|
sl@0
|
3599 |
iTail(NULL)
|
sl@0
|
3600 |
{
|
sl@0
|
3601 |
}
|
sl@0
|
3602 |
|
sl@0
|
3603 |
TUsbcScAlternateSettingList::~TUsbcScAlternateSettingList()
|
sl@0
|
3604 |
{
|
sl@0
|
3605 |
}
|
sl@0
|
3606 |
|
sl@0
|
3607 |
|
sl@0
|
3608 |
|
sl@0
|
3609 |
/*****************************************************************************\
|
sl@0
|
3610 |
* TUsbcDeviceStatusQueue *
|
sl@0
|
3611 |
* *
|
sl@0
|
3612 |
* *
|
sl@0
|
3613 |
* *
|
sl@0
|
3614 |
\*****************************************************************************/
|
sl@0
|
3615 |
|
sl@0
|
3616 |
|
sl@0
|
3617 |
TUsbcDeviceStatusQueue::TUsbcDeviceStatusQueue()
|
sl@0
|
3618 |
{
|
sl@0
|
3619 |
FlushQueue();
|
sl@0
|
3620 |
}
|
sl@0
|
3621 |
|
sl@0
|
3622 |
|
sl@0
|
3623 |
void TUsbcDeviceStatusQueue::FlushQueue()
|
sl@0
|
3624 |
{
|
sl@0
|
3625 |
for (TInt i = 0; i < KUsbDeviceStatusQueueDepth; i++)
|
sl@0
|
3626 |
{
|
sl@0
|
3627 |
iDeviceStatusQueue[i] = KUsbDeviceStatusNull;
|
sl@0
|
3628 |
}
|
sl@0
|
3629 |
iStatusQueueHead = 0;
|
sl@0
|
3630 |
}
|
sl@0
|
3631 |
|
sl@0
|
3632 |
|
sl@0
|
3633 |
void TUsbcDeviceStatusQueue::AddStatusToQueue(TUint32 aDeviceStatus)
|
sl@0
|
3634 |
{
|
sl@0
|
3635 |
// Only add a new status if it is not a duplicate of the one at the head of the queue
|
sl@0
|
3636 |
if (!(iStatusQueueHead != 0 &&
|
sl@0
|
3637 |
iDeviceStatusQueue[iStatusQueueHead - 1] == aDeviceStatus))
|
sl@0
|
3638 |
{
|
sl@0
|
3639 |
if (iStatusQueueHead == KUsbDeviceStatusQueueDepth)
|
sl@0
|
3640 |
{
|
sl@0
|
3641 |
// Discard item at tail of queue
|
sl@0
|
3642 |
TUint32 status;
|
sl@0
|
3643 |
GetDeviceQueuedStatus(status);
|
sl@0
|
3644 |
}
|
sl@0
|
3645 |
iDeviceStatusQueue[iStatusQueueHead] = aDeviceStatus;
|
sl@0
|
3646 |
iStatusQueueHead++;
|
sl@0
|
3647 |
}
|
sl@0
|
3648 |
}
|
sl@0
|
3649 |
|
sl@0
|
3650 |
|
sl@0
|
3651 |
TInt TUsbcDeviceStatusQueue::GetDeviceQueuedStatus(TUint32& aDeviceStatus)
|
sl@0
|
3652 |
{
|
sl@0
|
3653 |
TInt r = KErrNone;
|
sl@0
|
3654 |
if (iStatusQueueHead <= 0)
|
sl@0
|
3655 |
{
|
sl@0
|
3656 |
r = KErrGeneral;
|
sl@0
|
3657 |
aDeviceStatus = KUsbDeviceStatusNull;
|
sl@0
|
3658 |
}
|
sl@0
|
3659 |
else
|
sl@0
|
3660 |
{
|
sl@0
|
3661 |
aDeviceStatus = iDeviceStatusQueue[0];
|
sl@0
|
3662 |
for(TInt i = 1; i < KUsbDeviceStatusQueueDepth; i++)
|
sl@0
|
3663 |
{
|
sl@0
|
3664 |
TUint32 s = iDeviceStatusQueue[i];
|
sl@0
|
3665 |
iDeviceStatusQueue[i - 1] = s;
|
sl@0
|
3666 |
}
|
sl@0
|
3667 |
iStatusQueueHead--;
|
sl@0
|
3668 |
iDeviceStatusQueue[KUsbDeviceStatusQueueDepth - 1] = KUsbDeviceStatusNull;
|
sl@0
|
3669 |
}
|
sl@0
|
3670 |
return r;
|
sl@0
|
3671 |
}
|
sl@0
|
3672 |
|
sl@0
|
3673 |
// End TUsbcDeviceStatusQueue
|
sl@0
|
3674 |
|
sl@0
|
3675 |
//---
|
sl@0
|
3676 |
|