Esempio n. 1
0
File: fwd.c Progetto: KHATEEBNSIT/AP
static a_uint32_t
fwd_chunk_len(fwd_softc_t *sc)
{
    a_uint32_t left, max_chunk = FWD_MAX_CHUNK;
    
    left     =   sc->size - sc->offset;
    return(adf_os_min(left, max_chunk));
}
Esempio n. 2
0
LOCAL void _HTC_SendMsg(htc_handle_t htcHandle, HTC_ENDPOINT_ID EndpointID,
			adf_nbuf_t pBuffers)
{
	HTC_FRAME_HDR *pHTCHdr;
	int totsz;
	HTC_CONTEXT *pHTC = (HTC_CONTEXT *)htcHandle;  
	HTC_BUF_CONTEXT *ctx;
    
	ctx = (HTC_BUF_CONTEXT *)adf_nbuf_get_priv(pBuffers);
    
	/* init total size (this does not include the space we will put in for the HTC header) */
	totsz = adf_nbuf_len(pBuffers);
    
	/* the first buffer stores the header */
        /* back up buffer by a header size when we pass it down, by agreed upon convention the caller
	 * points the buffer to it's payload and leaves head room for the HTC header  
	 * Note: in HTCSendDoneHandler(), we undo this so that the caller get's it's buffer
	 * back untainted */   
	pHTCHdr = (HTC_FRAME_HDR *)adf_nbuf_push_head(pBuffers, HTC_HDR_LENGTH);
    
	/* flag that this is the header buffer that was modified */
	ctx->htc_flags |= HTC_FLAGS_BUF_HDR;   
	/* mark where this buffer came from */
	ctx->end_point = EndpointID;      
	/* the header start is ALWAYS aligned since we DMA it directly */

        /* set some fields, the rest of them will be filled below when we check for
	 * trailer space */
	pHTCHdr->Flags = 0;
	pHTCHdr->EndpointID = EndpointID;    
       
	/* check opportunistically if we can return any reports via a trailer */
	do {
		int               room,i,totalReportBytes;
		A_UINT32          creditsPendingMap, compareMask;
		HTC_CREDIT_REPORT *pCreditRpt;
		HTC_RECORD_HDR    *pRecHdr;
		int               pipeMaxLen;
		A_UINT32          roomForPipeMaxLen;
                          
		/* figure out how much room the last buffer can spare */
		pipeMaxLen = HIF_get_max_msg_len(pHTC->hifHandle,
						 pHTC->Endpoints[EndpointID].DownLinkPipeID);
		roomForPipeMaxLen = pipeMaxLen - adf_nbuf_headroom(pBuffers) - adf_nbuf_len(pBuffers);
		if ( roomForPipeMaxLen < 0 ) {
			roomForPipeMaxLen = 0;
		}
                        
		room = adf_os_min( adf_nbuf_tailroom(pBuffers), roomForPipeMaxLen);
		if (room < (int)(sizeof(HTC_CREDIT_REPORT) + sizeof(HTC_RECORD_HDR))) {
			/* no room for any reports */
			break;    
		}   
		/* note, a record header only has 8 bit fields, so this is safe.
		 * we need an uncached pointer here too */            
		totalReportBytes = 0;
        
		/* get a copy */        
		creditsPendingMap = pHTC->EpCreditPendingMap;   
                           
		/* test pending map to see if we can send a report , if any
		 * credits are available, we might as well send them on the 
		 * unused space in the buffer */
		if (creditsPendingMap) { 
            
			pRecHdr = (HTC_RECORD_HDR *)adf_nbuf_put_tail(pBuffers,
							      sizeof(HTC_RECORD_HDR));
            
			/* set the ID, the length will be updated with the number of credit reports we
			 * can fit (see below) */
			pRecHdr->RecordID = HTC_RECORD_CREDITS;
			pRecHdr->Length = 0;
			/* the credit report follows the record header */         
			totalReportBytes += sizeof(HTC_RECORD_HDR);
			room -= sizeof(HTC_RECORD_HDR);
            
			/* walkthrough pending credits map and build the records */
			for (i = 0; 
			     (creditsPendingMap != 0) && (room >= (int)sizeof(HTC_CREDIT_REPORT)); 
			     i++) {                
				compareMask = (1 << i);
				if (compareMask & creditsPendingMap) {
                        
					pCreditRpt = (HTC_CREDIT_REPORT *)adf_nbuf_put_tail(pBuffers,
									    sizeof(HTC_CREDIT_REPORT));
                                    
					/* clear pending mask, we are going to return all these credits */
					creditsPendingMap &= ~(compareMask);
					/* add this record */
					pCreditRpt->EndpointID = i;
					pCreditRpt->Credits = (A_UINT8)pHTC->Endpoints[i].CreditsToReturn;
					/* remove pending credits, we always send deltas */
					pHTC->Endpoints[i].CreditsToReturn = 0; 
					/* adjust new threshold for this endpoint if needed */
					CHECK_AND_ADJUST_CREDIT_THRESHOLD(&pHTC->Endpoints[i]);
					/* update this record length */
					pRecHdr->Length += sizeof(HTC_CREDIT_REPORT);
					room -= sizeof(HTC_CREDIT_REPORT);
					totalReportBytes += sizeof(HTC_CREDIT_REPORT);

					if ( room < sizeof(HTC_CREDIT_REPORT) ) {
						break;
					}
				}
			}
            
			/* update new pending credits map */       
			pHTC->EpCreditPendingMap = creditsPendingMap;
		}
        
		if (totalReportBytes <= 0) {
			break;
		}
        
		/* must fit into a byte, this should never actually happen since
		 * the maximum possible number of endpoints is 32. 
		 * The trailer can have at most 1 credit record with up to 32  reports in the record.
		 * The trailer can have at most 1 lookahead record with only 1 lookahead report in the record.
		 */
        
		/* set header option bytes */ 
		pHTCHdr->ControlBytes[0] = totalReportBytes;
		/* HTC frame contains a trailer */
		pHTCHdr->Flags |= HTC_FLAGS_RECV_TRAILER;
		/* increment total size by the reports we added */
		totsz += totalReportBytes;
		/* adjust the last buffer we used for adding on the trailer */                                 
	} while (FALSE);
          
	if (totsz == 0) {
	}
    
	/* set length for message (this includes any reports that were added above) */
	pHTCHdr->PayloadLen = adf_os_htons(totsz);  
	HIF_send_buffer(pHTC->hifHandle, pHTC->Endpoints[EndpointID].DownLinkPipeID, pBuffers);       
}