|  | @@ -359,3 +359,34 @@ int xfer_seek ( struct interface *intf, off_t offset ) {
 | 
		
	
		
			
			| 359 | 359 |  
 | 
		
	
		
			
			| 360 | 360 |  	return xfer_deliver ( intf, iobuf, &meta );
 | 
		
	
		
			
			| 361 | 361 |  }
 | 
		
	
		
			
			|  | 362 | +
 | 
		
	
		
			
			|  | 363 | +/**
 | 
		
	
		
			
			|  | 364 | + * Check that data is delivered strictly in order
 | 
		
	
		
			
			|  | 365 | + *
 | 
		
	
		
			
			|  | 366 | + * @v meta		Data transfer metadata
 | 
		
	
		
			
			|  | 367 | + * @v pos		Current position
 | 
		
	
		
			
			|  | 368 | + * @v len		Length of data
 | 
		
	
		
			
			|  | 369 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 370 | + */
 | 
		
	
		
			
			|  | 371 | +int xfer_check_order ( struct xfer_metadata *meta, size_t *pos, size_t len ) {
 | 
		
	
		
			
			|  | 372 | +	size_t new_pos;
 | 
		
	
		
			
			|  | 373 | +
 | 
		
	
		
			
			|  | 374 | +	/* Allow out-of-order zero-length packets (as used by xfer_seek()) */
 | 
		
	
		
			
			|  | 375 | +	if ( len == 0 )
 | 
		
	
		
			
			|  | 376 | +		return 0;
 | 
		
	
		
			
			|  | 377 | +
 | 
		
	
		
			
			|  | 378 | +	/* Calculate position of this delivery */
 | 
		
	
		
			
			|  | 379 | +	new_pos = *pos;
 | 
		
	
		
			
			|  | 380 | +	if ( meta->flags & XFER_FL_ABS_OFFSET )
 | 
		
	
		
			
			|  | 381 | +		new_pos = 0;
 | 
		
	
		
			
			|  | 382 | +	new_pos += meta->offset;
 | 
		
	
		
			
			|  | 383 | +
 | 
		
	
		
			
			|  | 384 | +	/* Fail if delivery position is not equal to current position */
 | 
		
	
		
			
			|  | 385 | +	if ( new_pos != *pos )
 | 
		
	
		
			
			|  | 386 | +		return -EPROTO;
 | 
		
	
		
			
			|  | 387 | +
 | 
		
	
		
			
			|  | 388 | +	/* Update current position */
 | 
		
	
		
			
			|  | 389 | +	*pos += len;
 | 
		
	
		
			
			|  | 390 | +
 | 
		
	
		
			
			|  | 391 | +	return 0;
 | 
		
	
		
			
			|  | 392 | +}
 |