/* Start HTC, enable interrupts and let the target know host has finished setup */ A_STATUS HTCStart(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_PACKET *pPacket; A_STATUS status; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); printk("HTCStart Enter\n"); /* make sure interrupts are disabled at the chip level, * this function can be called again from a reboot of the target without shutting down HTC */ DevDisableInterrupts(&target->Device); /* make sure state is cleared again */ target->HTCStateFlags = 0; /* now that we are starting, push control receive buffers into the * HTC control endpoint */ while (1) { pPacket = HTC_ALLOC_CONTROL_RX(target); if (NULL == pPacket) { break; } HTCAddReceivePkt((HTC_HANDLE)target,pPacket); } do { AR_DEBUG_ASSERT(target->InitCredits != NULL); AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL); AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL); /* call init credits callback to do the distribution , * NOTE: the first entry in the distribution list is ENDPOINT_0, so * we pass the start of the list after this one. */ target->InitCredits(target->pCredDistContext, target->EpCreditDistributionListHead->pNext, target->TargetCredits); if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) { DumpCreditDistStates(target); } /* the caller is done connecting to services, so we can indicate to the * target that the setup phase is complete */ status = HTCSendSetupComplete(target); if (A_FAILED(status)) { break; } /* unmask interrupts */ status = DevUnmaskInterrupts(&target->Device); if (A_FAILED(status)) { HTCStop(target); } } while (FALSE); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); printk("HTCStart Exit\n"); return status; }
/* synchronously wait for a control message from the target, * This function is used at initialization time ONLY. At init messages * on ENDPOINT 0 are expected. */ A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) { A_STATUS status; A_UINT32 lookAhead; HTC_PACKET *pPacket = NULL; HTC_FRAME_HDR *pHdr; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n")); do { *ppControlPacket = NULL; /* call the polling function to see if we have a message */ status = DevPollMboxMsgRecv(&target->Device, &lookAhead, HTC_TARGET_RESPONSE_TIMEOUT); if (A_FAILED(status)) { break; } AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead)); /* check the lookahead */ pHdr = (HTC_FRAME_HDR *)&lookAhead; if (pHdr->EndpointID != ENDPOINT_0) { /* unexpected endpoint number, should be zero */ AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; break; } if (A_FAILED(status)) { /* bad message */ AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; break; } pPacket = HTC_ALLOC_CONTROL_RX(target); if (pPacket == NULL) { AR_DEBUG_ASSERT(FALSE); status = A_NO_MEMORY; break; } pPacket->HTCReserved = lookAhead; pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; if (pPacket->ActualLength > pPacket->BufferLength) { AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; break; } /* we want synchronous operation */ pPacket->Completion = NULL; /* get the message from the device, this will block */ status = HTCIssueRecv(target, pPacket); if (A_FAILED(status)) { break; } /* process receive header */ status = HTCProcessRecvHeader(target,pPacket,NULL); pPacket->Status = status; if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n", status)); break; } /* give the caller this control message packet, they are responsible to free */ *ppControlPacket = pPacket; } while (FALSE); if (A_FAILED(status)) { if (pPacket != NULL) { /* cleanup buffer on error */ HTC_FREE_CONTROL_RX(target,pPacket); } } AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCWaitforControlMessage \n")); return status; }