3 * Copyright (c) 2007 Atheros Communications Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation;
11 * Software distributed under the License is distributed on an "AS
12 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 * implied. See the License for the specific language governing
14 * rights and limitations under the License.
20 #include "htc_internal.h"
22 #define HTCIssueRecv(t, p) \
23 DevRecvPacket(&(t)->Device, \
27 #define DO_RCV_COMPLETION(t,p,e) \
29 if ((p)->ActualLength > 0) { \
30 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" completing packet 0x%X (%d bytes) on ep : %d \n", \
31 (A_UINT32)(p), (p)->ActualLength, (p)->Endpoint)); \
32 (e)->EpCallBacks.EpRecv((e)->EpCallBacks.pContext, \
35 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" recycling empty packet \n")); \
36 HTC_RECYCLE_RX_PKT((t), (p)); \
40 #ifdef HTC_EP_STAT_PROFILING
41 #define HTC_RX_STAT_PROFILE(t,ep,lookAhead) \
44 INC_HTC_EP_STAT((ep), RxReceived, 1); \
45 if ((lookAhead) != 0) { \
46 INC_HTC_EP_STAT((ep), RxLookAheads, 1); \
51 #define HTC_RX_STAT_PROFILE(t,ep,lookAhead)
54 static INLINE A_STATUS
HTCProcessTrailer(HTC_TARGET
*target
,
57 A_UINT32
*pNextLookAhead
,
58 HTC_ENDPOINT_ID FromEndpoint
)
60 HTC_RECORD_HDR
*pRecord
;
62 HTC_LOOKAHEAD_REPORT
*pLookAhead
;
67 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
, ("+HTCProcessTrailer (length:%d) \n", Length
));
69 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV
)) {
70 AR_DEBUG_PRINTBUF(pBuffer
,Length
,"Recv Trailer");
73 pOrigBuffer
= pBuffer
;
79 if (Length
< sizeof(HTC_RECORD_HDR
)) {
83 /* these are byte aligned structs */
84 pRecord
= (HTC_RECORD_HDR
*)pBuffer
;
85 Length
-= sizeof(HTC_RECORD_HDR
);
86 pBuffer
+= sizeof(HTC_RECORD_HDR
);
88 if (pRecord
->Length
> Length
) {
89 /* no room left in buffer for record */
90 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
91 (" invalid record length: %d (id:%d) buffer has: %d bytes left \n",
92 pRecord
->Length
, pRecord
->RecordID
, Length
));
96 /* start of record follows the header */
99 switch (pRecord
->RecordID
) {
100 case HTC_RECORD_CREDITS
:
101 AR_DEBUG_ASSERT(pRecord
->Length
>= sizeof(HTC_CREDIT_REPORT
));
102 HTCProcessCreditRpt(target
,
103 (HTC_CREDIT_REPORT
*)pRecordBuf
,
104 pRecord
->Length
/ (sizeof(HTC_CREDIT_REPORT
)),
107 case HTC_RECORD_LOOKAHEAD
:
108 AR_DEBUG_ASSERT(pRecord
->Length
>= sizeof(HTC_LOOKAHEAD_REPORT
));
109 pLookAhead
= (HTC_LOOKAHEAD_REPORT
*)pRecordBuf
;
110 if ((pLookAhead
->PreValid
== ((~pLookAhead
->PostValid
) & 0xFF)) &&
111 (pNextLookAhead
!= NULL
)) {
113 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,
114 (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) \n",
115 pLookAhead
->PreValid
,
116 pLookAhead
->PostValid
));
118 /* look ahead bytes are valid, copy them over */
119 ((A_UINT8
*)pNextLookAhead
)[0] = pLookAhead
->LookAhead
[0];
120 ((A_UINT8
*)pNextLookAhead
)[1] = pLookAhead
->LookAhead
[1];
121 ((A_UINT8
*)pNextLookAhead
)[2] = pLookAhead
->LookAhead
[2];
122 ((A_UINT8
*)pNextLookAhead
)[3] = pLookAhead
->LookAhead
[3];
124 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV
)) {
125 DebugDumpBytes((A_UINT8
*)pNextLookAhead
,4,"Next Look Ahead");
130 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, (" unhandled record: id:%d length:%d \n",
131 pRecord
->RecordID
, pRecord
->Length
));
135 if (A_FAILED(status
)) {
139 /* advance buffer past this record for next time around */
140 pBuffer
+= pRecord
->Length
;
141 Length
-= pRecord
->Length
;
144 if (A_FAILED(status
)) {
145 DebugDumpBytes(pOrigBuffer
,origLength
,"BAD Recv Trailer");
148 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
, ("-HTCProcessTrailer \n"));
153 /* process a received message (i.e. strip off header, process any trailer data)
154 * note : locks must be released when this function is called */
155 static A_STATUS
HTCProcessRecvHeader(HTC_TARGET
*target
, HTC_PACKET
*pPacket
, A_UINT32
*pNextLookAhead
)
159 A_STATUS status
= A_OK
;
163 pBuf
= pPacket
->pBuffer
;
165 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
, ("+HTCProcessRecvHeader \n"));
167 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV
)) {
168 AR_DEBUG_PRINTBUF(pBuf
,pPacket
->ActualLength
,"HTC Recv PKT");
172 /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to
173 * retrieve 16 bit fields */
174 payloadLen
= A_GET_UINT16_FIELD(pBuf
, HTC_FRAME_HDR
, PayloadLen
);
176 ((A_UINT8
*)&lookAhead
)[0] = pBuf
[0];
177 ((A_UINT8
*)&lookAhead
)[1] = pBuf
[1];
178 ((A_UINT8
*)&lookAhead
)[2] = pBuf
[2];
179 ((A_UINT8
*)&lookAhead
)[3] = pBuf
[3];
181 if (lookAhead
!= pPacket
->HTCReserved
) {
182 /* somehow the lookahead that gave us the full read length did not
183 * reflect the actual header in the pending message */
184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
185 ("HTCProcessRecvHeader, lookahead mismatch! \n"));
186 DebugDumpBytes((A_UINT8
*)&pPacket
->HTCReserved
,4,"Expected Message LookAhead");
187 DebugDumpBytes(pBuf
,sizeof(HTC_FRAME_HDR
),"Current Frame Header");
188 #ifdef HTC_CAPTURE_LAST_FRAME
189 DebugDumpBytes((A_UINT8
*)&target
->LastFrameHdr
,sizeof(HTC_FRAME_HDR
),"Last Frame Header");
190 if (target
->LastTrailerLength
!= 0) {
191 DebugDumpBytes(target
->LastTrailer
,
192 target
->LastTrailerLength
,
201 temp
= A_GET_UINT8_FIELD(pBuf
, HTC_FRAME_HDR
, Flags
);
203 if (temp
& HTC_FLAGS_RECV_TRAILER
) {
204 /* this packet has a trailer */
206 /* extract the trailer length in control byte 0 */
207 temp
= A_GET_UINT8_FIELD(pBuf
, HTC_FRAME_HDR
, ControlBytes
[0]);
209 if ((temp
< sizeof(HTC_RECORD_HDR
)) || (temp
> payloadLen
)) {
210 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
211 ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n",
217 /* process trailer data that follows HDR + application payload */
218 status
= HTCProcessTrailer(target
,
219 (pBuf
+ HTC_HDR_LENGTH
+ payloadLen
- temp
),
224 if (A_FAILED(status
)) {
228 #ifdef HTC_CAPTURE_LAST_FRAME
229 A_MEMCPY(target
->LastTrailer
, (pBuf
+ HTC_HDR_LENGTH
+ payloadLen
- temp
), temp
);
230 target
->LastTrailerLength
= temp
;
232 /* trim length by trailer bytes */
233 pPacket
->ActualLength
-= temp
;
235 #ifdef HTC_CAPTURE_LAST_FRAME
237 target
->LastTrailerLength
= 0;
241 /* if we get to this point, the packet is good */
242 /* remove header and adjust length */
243 pPacket
->pBuffer
+= HTC_HDR_LENGTH
;
244 pPacket
->ActualLength
-= HTC_HDR_LENGTH
;
248 if (A_FAILED(status
)) {
249 /* dump the whole packet */
250 DebugDumpBytes(pBuf
,pPacket
->ActualLength
,"BAD HTC Recv PKT");
252 #ifdef HTC_CAPTURE_LAST_FRAME
253 A_MEMCPY(&target
->LastFrameHdr
,pBuf
,sizeof(HTC_FRAME_HDR
));
255 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV
)) {
256 if (pPacket
->ActualLength
> 0) {
257 AR_DEBUG_PRINTBUF(pPacket
->pBuffer
,pPacket
->ActualLength
,"HTC - Application Msg");
262 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
, ("-HTCProcessRecvHeader \n"));
266 /* asynchronous completion handler for recv packet fetching, when the device layer
267 * completes a read request, it will call this completion handler */
268 void HTCRecvCompleteHandler(void *Context
, HTC_PACKET
*pPacket
)
270 HTC_TARGET
*target
= (HTC_TARGET
*)Context
;
271 HTC_ENDPOINT
*pEndpoint
;
272 A_UINT32 nextLookAhead
= 0;
275 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
, ("+HTCRecvCompleteHandler (status:%d, ep:%d) \n",
276 pPacket
->Status
, pPacket
->Endpoint
));
278 AR_DEBUG_ASSERT(pPacket
->Endpoint
< ENDPOINT_MAX
);
279 pEndpoint
= &target
->EndPoint
[pPacket
->Endpoint
];
280 pPacket
->Completion
= NULL
;
282 /* get completion status */
283 status
= pPacket
->Status
;
286 if (A_FAILED(status
)) {
287 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n",
288 pPacket
->Status
, pPacket
->Endpoint
));
291 /* process the header for any trailer data */
292 status
= HTCProcessRecvHeader(target
,pPacket
,&nextLookAhead
);
294 if (A_FAILED(status
)) {
297 /* was there a lookahead for the next packet? */
298 if (nextLookAhead
!= 0) {
300 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,
301 ("HTCRecvCompleteHandler - next look ahead was non-zero : 0x%X \n",
303 /* we have another packet, get the next packet fetch started (pipelined) before
304 * we call into the endpoint's callback, this will start another async request */
305 nextStatus
= HTCRecvMessagePendingHandler(target
,nextLookAhead
,NULL
);
306 if (A_EPROTO
== nextStatus
) {
307 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
308 ("Next look ahead from recv header was INVALID\n"));
309 DebugDumpBytes((A_UINT8
*)&nextLookAhead
,
311 "BAD lookahead from lookahead report");
314 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,
315 ("HTCRecvCompleteHandler - rechecking for more messages...\n"));
316 /* if we did not get anything on the look-ahead,
317 * call device layer to asynchronously re-check for messages. If we can keep the async
318 * processing going we get better performance. If there is a pending message we will keep processing
319 * messages asynchronously which should pipeline things nicely */
320 DevCheckPendingRecvMsgsAsync(&target
->Device
);
323 HTC_RX_STAT_PROFILE(target
,pEndpoint
,nextLookAhead
);
324 DO_RCV_COMPLETION(target
,pPacket
,pEndpoint
);
328 if (A_FAILED(status
)) {
329 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
330 ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n",
332 /* recyle this packet */
333 HTC_RECYCLE_RX_PKT(target
, pPacket
);
336 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
, ("-HTCRecvCompleteHandler\n"));
339 /* synchronously wait for a control message from the target,
340 * This function is used at initialization time ONLY. At init messages
341 * on ENDPOINT 0 are expected. */
342 A_STATUS
HTCWaitforControlMessage(HTC_TARGET
*target
, HTC_PACKET
**ppControlPacket
)
346 HTC_PACKET
*pPacket
= NULL
;
349 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,("+HTCWaitforControlMessage \n"));
353 *ppControlPacket
= NULL
;
355 /* call the polling function to see if we have a message */
356 status
= DevPollMboxMsgRecv(&target
->Device
,
358 HTC_TARGET_RESPONSE_TIMEOUT
);
360 if (A_FAILED(status
)) {
364 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,
365 ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead
));
367 /* check the lookahead */
368 pHdr
= (HTC_FRAME_HDR
*)&lookAhead
;
370 if (pHdr
->EndpointID
!= ENDPOINT_0
) {
371 /* unexpected endpoint number, should be zero */
372 AR_DEBUG_ASSERT(FALSE
);
377 if (A_FAILED(status
)) {
379 AR_DEBUG_ASSERT(FALSE
);
384 pPacket
= HTC_ALLOC_CONTROL_RX(target
);
386 if (pPacket
== NULL
) {
387 AR_DEBUG_ASSERT(FALSE
);
388 status
= A_NO_MEMORY
;
392 pPacket
->HTCReserved
= lookAhead
;
393 pPacket
->ActualLength
= pHdr
->PayloadLen
+ HTC_HDR_LENGTH
;
395 if (pPacket
->ActualLength
> pPacket
->BufferLength
) {
396 AR_DEBUG_ASSERT(FALSE
);
401 /* we want synchronous operation */
402 pPacket
->Completion
= NULL
;
404 /* get the message from the device, this will block */
405 status
= HTCIssueRecv(target
, pPacket
);
407 if (A_FAILED(status
)) {
411 /* process receive header */
412 status
= HTCProcessRecvHeader(target
,pPacket
,NULL
);
414 pPacket
->Status
= status
;
416 if (A_FAILED(status
)) {
417 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
418 ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n",
423 /* give the caller this control message packet, they are responsible to free */
424 *ppControlPacket
= pPacket
;
428 if (A_FAILED(status
)) {
429 if (pPacket
!= NULL
) {
430 /* cleanup buffer on error */
431 HTC_FREE_CONTROL_RX(target
,pPacket
);
435 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,("-HTCWaitforControlMessage \n"));
440 /* callback when device layer or lookahead report parsing detects a pending message */
441 A_STATUS
HTCRecvMessagePendingHandler(void *Context
, A_UINT32 LookAhead
, A_BOOL
*pAsyncProc
)
443 HTC_TARGET
*target
= (HTC_TARGET
*)Context
;
444 A_STATUS status
= A_OK
;
445 HTC_PACKET
*pPacket
= NULL
;
447 HTC_ENDPOINT
*pEndpoint
;
448 A_BOOL asyncProc
= FALSE
;
450 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,("+HTCRecvMessagePendingHandler LookAhead:0x%X \n",LookAhead
));
452 if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target
->Device
)) {
453 /* We use async mode to get the packets if the device layer supports it.
454 * The device layer interfaces with HIF in which HIF may have restrictions on
455 * how interrupts are processed */
459 if (pAsyncProc
!= NULL
) {
460 /* indicate to caller how we decided to process this */
461 *pAsyncProc
= asyncProc
;
466 pHdr
= (HTC_FRAME_HDR
*)&LookAhead
;
468 if (pHdr
->EndpointID
>= ENDPOINT_MAX
) {
469 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("Invalid Endpoint in look-ahead: %d \n",pHdr
->EndpointID
));
470 /* invalid endpoint */
475 if (pHdr
->PayloadLen
> HTC_MAX_PAYLOAD_LENGTH
) {
476 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("Payload length %d exceeds max HTC : %d !\n",
477 pHdr
->PayloadLen
, HTC_MAX_PAYLOAD_LENGTH
));
482 pEndpoint
= &target
->EndPoint
[pHdr
->EndpointID
];
484 if (0 == pEndpoint
->ServiceID
) {
485 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("Endpoint %d is not connected !\n",pHdr
->EndpointID
));
486 /* endpoint isn't even connected */
491 /* lock RX to get a buffer */
494 /* get a packet from the endpoint recv queue */
495 pPacket
= HTC_PACKET_DEQUEUE(&pEndpoint
->RxBuffers
);
497 if (NULL
== pPacket
) {
498 /* check for refill handler */
499 if (pEndpoint
->EpCallBacks
.EpRecvRefill
!= NULL
) {
500 UNLOCK_HTC_RX(target
);
501 /* call the re-fill handler */
502 pEndpoint
->EpCallBacks
.EpRecvRefill(pEndpoint
->EpCallBacks
.pContext
,
505 /* check if we have more buffers */
506 pPacket
= HTC_PACKET_DEQUEUE(&pEndpoint
->RxBuffers
);
511 if (NULL
== pPacket
) {
512 /* this is not an error, we simply need to mark that we are waiting for buffers.*/
513 target
->HTCStateFlags
|= HTC_STATE_WAIT_BUFFERS
;
514 target
->EpWaitingForBuffers
= pHdr
->EndpointID
;
515 status
= A_NO_MEMORY
;
518 UNLOCK_HTC_RX(target
);
520 if (A_FAILED(status
)) {
525 AR_DEBUG_ASSERT(pPacket
->Endpoint
== pHdr
->EndpointID
);
527 /* make sure this message can fit in the endpoint buffer */
528 if ((pHdr
->PayloadLen
+ HTC_HDR_LENGTH
) > pPacket
->BufferLength
) {
529 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
530 ("Payload Length Error : header reports payload of: %d, endpoint buffer size: %d \n",
531 pHdr
->PayloadLen
, pPacket
->BufferLength
));
536 pPacket
->HTCReserved
= LookAhead
; /* set expected look ahead */
537 /* set the amount of data to fetch */
538 pPacket
->ActualLength
= pHdr
->PayloadLen
+ HTC_HDR_LENGTH
;
541 /* we use async mode to get the packet if the device layer supports it
542 * set our callback and context */
543 pPacket
->Completion
= HTCRecvCompleteHandler
;
544 pPacket
->pContext
= target
;
546 /* fully synchronous */
547 pPacket
->Completion
= NULL
;
550 /* go fetch the packet */
551 status
= HTCIssueRecv(target
, pPacket
);
553 if (A_FAILED(status
)) {
558 /* we did this asynchronously so we can get out of the loop, the asynch processing
559 * creates a chain of requests to continue processing pending messages in the
560 * context of callbacks */
564 /* in the sync case, we process the packet, check lookaheads and then repeat */
567 status
= HTCProcessRecvHeader(target
,pPacket
,&LookAhead
);
569 if (A_FAILED(status
)) {
573 HTC_RX_STAT_PROFILE(target
,pEndpoint
,LookAhead
);
574 DO_RCV_COMPLETION(target
,pPacket
,pEndpoint
);
578 if (0 == LookAhead
) {
584 if (A_NO_MEMORY
== status
) {
585 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
586 (" Endpoint :%d has no buffers, blocking receiver to prevent overrun.. \n",
588 /* try to stop receive at the device layer */
589 DevStopRecv(&target
->Device
, asyncProc
? DEV_STOP_RECV_ASYNC
: DEV_STOP_RECV_SYNC
);
591 } else if (A_FAILED(status
)) {
592 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
593 ("Failed to get pending message : LookAhead Value: 0x%X (status = %d) \n",
595 if (pPacket
!= NULL
) {
596 /* clean up packet on error */
597 HTC_RECYCLE_RX_PKT(target
, pPacket
);
601 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,("-HTCRecvMessagePendingHandler \n"));
606 /* Makes a buffer available to the HTC module */
607 A_STATUS
HTCAddReceivePkt(HTC_HANDLE HTCHandle
, HTC_PACKET
*pPacket
)
609 HTC_TARGET
*target
= GET_HTC_TARGET_FROM_HANDLE(HTCHandle
);
610 HTC_ENDPOINT
*pEndpoint
;
611 A_BOOL unblockRecv
= FALSE
;
612 A_STATUS status
= A_OK
;
614 AR_DEBUG_PRINTF(ATH_DEBUG_SEND
,
615 ("+- HTCAddReceivePkt: endPointId: %d, buffer: 0x%X, length: %d\n",
616 pPacket
->Endpoint
, (A_UINT32
)pPacket
->pBuffer
, pPacket
->BufferLength
));
620 if (HTC_STOPPING(target
)) {
621 status
= A_ECANCELED
;
625 AR_DEBUG_ASSERT(pPacket
->Endpoint
< ENDPOINT_MAX
);
627 pEndpoint
= &target
->EndPoint
[pPacket
->Endpoint
];
631 /* store receive packet */
632 HTC_PACKET_ENQUEUE(&pEndpoint
->RxBuffers
, pPacket
);
634 /* check if we are blocked waiting for a new buffer */
635 if (target
->HTCStateFlags
& HTC_STATE_WAIT_BUFFERS
) {
636 if (target
->EpWaitingForBuffers
== pPacket
->Endpoint
) {
637 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,(" receiver was blocked on ep:%d, unblocking.. \n",
638 target
->EpWaitingForBuffers
));
639 target
->HTCStateFlags
&= ~HTC_STATE_WAIT_BUFFERS
;
640 target
->EpWaitingForBuffers
= ENDPOINT_MAX
;
645 UNLOCK_HTC_RX(target
);
647 if (unblockRecv
&& !HTC_STOPPING(target
)) {
648 /* TODO : implement a buffer threshold count? */
649 DevEnableRecv(&target
->Device
,DEV_ENABLE_RECV_SYNC
);
657 static void HTCFlushEndpointRX(HTC_TARGET
*target
, HTC_ENDPOINT
*pEndpoint
)
664 pPacket
= HTC_PACKET_DEQUEUE(&pEndpoint
->RxBuffers
);
665 if (NULL
== pPacket
) {
668 UNLOCK_HTC_RX(target
);
669 pPacket
->Status
= A_ECANCELED
;
670 pPacket
->ActualLength
= 0;
671 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
, (" Flushing RX packet:0x%X, length:%d, ep:%d \n",
672 (A_UINT32
)pPacket
, pPacket
->BufferLength
, pPacket
->Endpoint
));
673 /* give the packet back */
674 pEndpoint
->EpCallBacks
.EpRecv(pEndpoint
->EpCallBacks
.pContext
,
679 UNLOCK_HTC_RX(target
);
684 void HTCFlushRecvBuffers(HTC_TARGET
*target
)
686 HTC_ENDPOINT
*pEndpoint
;
689 /* NOTE: no need to flush endpoint 0, these buffers were
690 * allocated as part of the HTC struct */
691 for (i
= ENDPOINT_1
; i
< ENDPOINT_MAX
; i
++) {
692 pEndpoint
= &target
->EndPoint
[i
];
693 if (pEndpoint
->ServiceID
== 0) {
697 HTCFlushEndpointRX(target
,pEndpoint
);