| 
				
			 | 
			
			
				
				@@ -66,88 +66,33 @@ void init_buffer ( struct buffer *buffer ) { 
			 | 
		
		
	
		
			
			| 
				66
			 | 
			
				66
			 | 
			
			
				
				 	DBG ( "BUFFER [%x,%x) initialised\n", buffer->start, buffer->end ); 
			 | 
		
		
	
		
			
			| 
				67
			 | 
			
				67
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				68
			 | 
			
				68
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				69
			 | 
			
				
			 | 
			
			
				
				-/** 
			 | 
		
		
	
		
			
			| 
				70
			 | 
			
				
			 | 
			
			
				
				- * Split a free block. 
			 | 
		
		
	
		
			
			| 
				71
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				72
			 | 
			
				
			 | 
			
			
				
				- * @v desc		A descriptor for the free block 
			 | 
		
		
	
		
			
			| 
				73
			 | 
			
				
			 | 
			
			
				
				- * @v block		Start address of the block 
			 | 
		
		
	
		
			
			| 
				74
			 | 
			
				
			 | 
			
			
				
				- * @v split		Address at which to split the block 
			 | 
		
		
	
		
			
			| 
				75
			 | 
			
				
			 | 
			
			
				
				- * @ret None		- 
			 | 
		
		
	
		
			
			| 
				76
			 | 
			
				
			 | 
			
			
				
				- * @err None		- 
			 | 
		
		
	
		
			
			| 
				77
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				78
			 | 
			
				
			 | 
			
			
				
				- * Split a free block into two separate free blocks.  If the split 
			 | 
		
		
	
		
			
			| 
				79
			 | 
			
				
			 | 
			
			
				
				- * point lies outside the block, no action is taken; this is not an 
			 | 
		
		
	
		
			
			| 
				80
			 | 
			
				
			 | 
			
			
				
				- * error. 
			 | 
		
		
	
		
			
			| 
				81
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				82
			 | 
			
				
			 | 
			
			
				
				- * @b NOTE: It is the reponsibility of the caller to ensure that there 
			 | 
		
		
	
		
			
			| 
				83
			 | 
			
				
			 | 
			
			
				
				- * is enough room in each of the two portions for a free block 
			 | 
		
		
	
		
			
			| 
				84
			 | 
			
				
			 | 
			
			
				
				- * descriptor (a @c struct @c buffer_free_block, except in the case of 
			 | 
		
		
	
		
			
			| 
				85
			 | 
			
				
			 | 
			
			
				
				- * a tail block which requires only a one byte descriptor).  If the 
			 | 
		
		
	
		
			
			| 
				86
			 | 
			
				
			 | 
			
			
				
				- * caller fails to do this, data corruption will occur. 
			 | 
		
		
	
		
			
			| 
				87
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				88
			 | 
			
				
			 | 
			
			
				
				- * In practice, this means that the granularity at which blocks are 
			 | 
		
		
	
		
			
			| 
				89
			 | 
			
				
			 | 
			
			
				
				- * split must be at least @c sizeof(struct @c buffer_free_block). 
			 | 
		
		
	
		
			
			| 
				90
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				91
			 | 
			
				
			 | 
			
			
				
				- */ 
			 | 
		
		
	
		
			
			| 
				92
			 | 
			
				
			 | 
			
			
				
				-static void split_free_block ( struct buffer_free_block *desc, 
			 | 
		
		
	
		
			
			| 
				93
			 | 
			
				
			 | 
			
			
				
				-			       physaddr_t block, physaddr_t split ) { 
			 | 
		
		
	
		
			
			| 
				94
			 | 
			
				
			 | 
			
			
				
				-	/* If split point is before start of block, do nothing */ 
			 | 
		
		
	
		
			
			| 
				95
			 | 
			
				
			 | 
			
			
				
				-	if ( split <= block ) 
			 | 
		
		
	
		
			
			| 
				96
			 | 
			
				
			 | 
			
			
				
				-		return; 
			 | 
		
		
	
		
			
			| 
				97
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				98
			 | 
			
				
			 | 
			
			
				
				-	/* If split point is after end of block, do nothing */ 
			 | 
		
		
	
		
			
			| 
				99
			 | 
			
				
			 | 
			
			
				
				-	if ( split >= desc->end ) 
			 | 
		
		
	
		
			
			| 
				100
			 | 
			
				
			 | 
			
			
				
				-		return; 
			 | 
		
		
	
		
			
			| 
				101
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				102
			 | 
			
				
			 | 
			
			
				
				-	DBG ( "BUFFER splitting [%x,%x) -> [%x,%x) [%x,%x)\n", 
			 | 
		
		
	
		
			
			| 
				103
			 | 
			
				
			 | 
			
			
				
				-	      block, desc->end, block, split, split, desc->end ); 
			 | 
		
		
	
		
			
			| 
				104
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				105
			 | 
			
				
			 | 
			
			
				
				-	/* Create descriptor for new free block */ 
			 | 
		
		
	
		
			
			| 
				106
			 | 
			
				
			 | 
			
			
				
				-	copy_to_phys ( split, &desc->tail, sizeof ( desc->tail ) ); 
			 | 
		
		
	
		
			
			| 
				107
			 | 
			
				
			 | 
			
			
				
				-	if ( ! desc->tail ) 
			 | 
		
		
	
		
			
			| 
				108
			 | 
			
				
			 | 
			
			
				
				-		copy_to_phys ( split, desc, sizeof ( *desc ) ); 
			 | 
		
		
	
		
			
			| 
				109
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				110
			 | 
			
				
			 | 
			
			
				
				-	/* Update descriptor for old free block */ 
			 | 
		
		
	
		
			
			| 
				111
			 | 
			
				
			 | 
			
			
				
				-	desc->tail = 0; 
			 | 
		
		
	
		
			
			| 
				112
			 | 
			
				
			 | 
			
			
				
				-	desc->next_free = split; 
			 | 
		
		
	
		
			
			| 
				113
			 | 
			
				
			 | 
			
			
				
				-	desc->end = split; 
			 | 
		
		
	
		
			
			| 
				114
			 | 
			
				
			 | 
			
			
				
				-	copy_to_phys ( block, desc, sizeof ( *desc ) ); 
			 | 
		
		
	
		
			
			| 
				115
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				
				+static inline int next_free_block ( struct buffer_free_block *block, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				
				+				    struct buffer *buffer ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				
				+	/* Move to next block */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				
				+	block->start = block->next; 
			 | 
		
		
	
		
			
			| 
				116
			 | 
			
				73
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				117
			 | 
			
				
			 | 
			
			
				
				-/** 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				
			 | 
			
			
				
				- * Mark a free block as used. 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				
			 | 
			
			
				
				- * @v buffer		The buffer containing the block 
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				
			 | 
			
			
				
				- * @v desc		A descriptor for the free block 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				
			 | 
			
			
				
				- * @v prev_block	Address of the previous block 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				
			 | 
			
			
				
				- * @ret None		- 
			 | 
		
		
	
		
			
			| 
				124
			 | 
			
				
			 | 
			
			
				
				- * @err None		- 
			 | 
		
		
	
		
			
			| 
				125
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				126
			 | 
			
				
			 | 
			
			
				
				- * Marks a free block as used, i.e. removes it from the free list. 
			 | 
		
		
	
		
			
			| 
				127
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				128
			 | 
			
				
			 | 
			
			
				
				- */ 
			 | 
		
		
	
		
			
			| 
				129
			 | 
			
				
			 | 
			
			
				
				-static inline void unfree_block ( struct buffer *buffer, 
			 | 
		
		
	
		
			
			| 
				130
			 | 
			
				
			 | 
			
			
				
				-				  struct buffer_free_block *desc, 
			 | 
		
		
	
		
			
			| 
				131
			 | 
			
				
			 | 
			
			
				
				-				  physaddr_t prev_block ) { 
			 | 
		
		
	
		
			
			| 
				132
			 | 
			
				
			 | 
			
			
				
				-	struct buffer_free_block prev_desc; 
			 | 
		
		
	
		
			
			| 
				133
			 | 
			
				
			 | 
			
			
				
				-	 
			 | 
		
		
	
		
			
			| 
				134
			 | 
			
				
			 | 
			
			
				
				-	/* If this is the first block, just update buffer->fill */ 
			 | 
		
		
	
		
			
			| 
				135
			 | 
			
				
			 | 
			
			
				
				-	if ( ! prev_block ) { 
			 | 
		
		
	
		
			
			| 
				136
			 | 
			
				
			 | 
			
			
				
				-		DBG ( "BUFFER marking [%x,%x) as used\n", 
			 | 
		
		
	
		
			
			| 
				137
			 | 
			
				
			 | 
			
			
				
				-		      buffer->start + buffer->fill, desc->end ); 
			 | 
		
		
	
		
			
			| 
				138
			 | 
			
				
			 | 
			
			
				
				-		buffer->fill = desc->next_free - buffer->start; 
			 | 
		
		
	
		
			
			| 
				139
			 | 
			
				
			 | 
			
			
				
				-		return; 
			 | 
		
		
	
		
			
			| 
				140
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				
				+	/* If at end of buffer, return 0 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				
				+	if ( block->start >= buffer->end ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				
				+		return 0; 
			 | 
		
		
	
		
			
			| 
				141
			 | 
			
				77
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				142
			 | 
			
				
			 | 
			
			
				
				-	/* Get descriptor for previous block (which cannot be a tail block) */ 
			 | 
		
		
	
		
			
			| 
				143
			 | 
			
				
			 | 
			
			
				
				-	copy_from_phys ( &prev_desc, prev_block, sizeof ( prev_desc ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				
				+	/* Set up ->next and ->end as for a tail block */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				
				+	block->next = block->end = buffer->end; 
			 | 
		
		
	
		
			
			| 
				144
			 | 
			
				80
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				145
			 | 
			
				
			 | 
			
			
				
				-	DBG ( "BUFFER marking [%x,%x) as used\n", 
			 | 
		
		
	
		
			
			| 
				146
			 | 
			
				
			 | 
			
			
				
				-	      prev_desc.next_free, desc->end ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				
				+	/* Read tail marker from block */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				
				+	copy_from_phys ( &block->tail, block->start, sizeof ( block->tail ) ); 
			 | 
		
		
	
		
			
			| 
				147
			 | 
			
				83
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				148
			 | 
			
				
			 | 
			
			
				
				-	/* Modify descriptor for previous block and write it back */ 
			 | 
		
		
	
		
			
			| 
				149
			 | 
			
				
			 | 
			
			
				
				-	prev_desc.next_free = desc->next_free; 
			 | 
		
		
	
		
			
			| 
				150
			 | 
			
				
			 | 
			
			
				
				-	copy_to_phys ( prev_block, &prev_desc, sizeof ( prev_desc ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				
				+	/* If not a tail block, read whole block descriptor from block */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				
				+	if ( ! block->tail ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				
				+		copy_from_phys ( block, block->start, sizeof ( *block ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				87
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				89
			 | 
			
			
				
				+	return 1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				
				+static inline void store_free_block ( struct buffer_free_block *block ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				
				+	copy_to_phys ( block->start, block, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				
				+		       ( block->tail ? 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				
				+			 sizeof ( block->tail ) : sizeof ( *block ) ) ); 
			 | 
		
		
	
		
			
			| 
				151
			 | 
			
				96
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				152
			 | 
			
				97
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				153
			 | 
			
				98
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -188,8 +133,7 @@ static inline void unfree_block ( struct buffer *buffer, 
			 | 
		
		
	
		
			
			| 
				188
			 | 
			
				133
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				189
			 | 
			
				134
			 | 
			
			
				
				 int fill_buffer ( struct buffer *buffer, const void *data, 
			 | 
		
		
	
		
			
			| 
				190
			 | 
			
				135
			 | 
			
			
				
				 		  off_t offset, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				191
			 | 
			
				
			 | 
			
			
				
				-	struct buffer_free_block desc; 
			 | 
		
		
	
		
			
			| 
				192
			 | 
			
				
			 | 
			
			
				
				-	physaddr_t block, prev_block; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				136
			 | 
			
			
				
				+	struct buffer_free_block block, before, after; 
			 | 
		
		
	
		
			
			| 
				193
			 | 
			
				137
			 | 
			
			
				
				 	physaddr_t data_start, data_end; 
			 | 
		
		
	
		
			
			| 
				194
			 | 
			
				138
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				195
			 | 
			
				139
			 | 
			
			
				
				 	/* Calculate start and end addresses of data */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -206,38 +150,48 @@ int fill_buffer ( struct buffer *buffer, const void *data, 
			 | 
		
		
	
		
			
			| 
				206
			 | 
			
				150
			 | 
			
			
				
				 		return 0; 
			 | 
		
		
	
		
			
			| 
				207
			 | 
			
				151
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				208
			 | 
			
				152
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				209
			 | 
			
				
			 | 
			
			
				
				-	/* Iterate through the buffer's free blocks */ 
			 | 
		
		
	
		
			
			| 
				210
			 | 
			
				
			 | 
			
			
				
				-	prev_block = 0; 
			 | 
		
		
	
		
			
			| 
				211
			 | 
			
				
			 | 
			
			
				
				-	block = buffer->start + buffer->fill; 
			 | 
		
		
	
		
			
			| 
				212
			 | 
			
				
			 | 
			
			
				
				-	while ( block < buffer->end ) { 
			 | 
		
		
	
		
			
			| 
				213
			 | 
			
				
			 | 
			
			
				
				-		/* Read block descriptor */ 
			 | 
		
		
	
		
			
			| 
				214
			 | 
			
				
			 | 
			
			
				
				-		desc.next_free = buffer->end; 
			 | 
		
		
	
		
			
			| 
				215
			 | 
			
				
			 | 
			
			
				
				-		desc.end = buffer->end; 
			 | 
		
		
	
		
			
			| 
				216
			 | 
			
				
			 | 
			
			
				
				-		copy_from_phys ( &desc.tail, block, sizeof ( desc.tail ) ); 
			 | 
		
		
	
		
			
			| 
				217
			 | 
			
				
			 | 
			
			
				
				-		if ( ! desc.tail ) 
			 | 
		
		
	
		
			
			| 
				218
			 | 
			
				
			 | 
			
			
				
				-			copy_from_phys ( &desc, block, sizeof ( desc ) ); 
			 | 
		
		
	
		
			
			| 
				219
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				220
			 | 
			
				
			 | 
			
			
				
				-		/* Split block at data start and end markers */ 
			 | 
		
		
	
		
			
			| 
				221
			 | 
			
				
			 | 
			
			
				
				-		split_free_block ( &desc, block, data_start ); 
			 | 
		
		
	
		
			
			| 
				222
			 | 
			
				
			 | 
			
			
				
				-		split_free_block ( &desc, block, data_end ); 
			 | 
		
		
	
		
			
			| 
				223
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				224
			 | 
			
				
			 | 
			
			
				
				-		/* Block is now either completely contained by or 
			 | 
		
		
	
		
			
			| 
				225
			 | 
			
				
			 | 
			
			
				
				-		 * completely outside the data area 
			 | 
		
		
	
		
			
			| 
				226
			 | 
			
				
			 | 
			
			
				
				-		 */ 
			 | 
		
		
	
		
			
			| 
				227
			 | 
			
				
			 | 
			
			
				
				-		if ( ( block >= data_start ) && ( block < data_end ) ) { 
			 | 
		
		
	
		
			
			| 
				228
			 | 
			
				
			 | 
			
			
				
				-			/* Block is within the data area */ 
			 | 
		
		
	
		
			
			| 
				229
			 | 
			
				
			 | 
			
			
				
				-			unfree_block ( buffer, &desc, prev_block ); 
			 | 
		
		
	
		
			
			| 
				230
			 | 
			
				
			 | 
			
			
				
				-			copy_to_phys ( block, data + ( block - data_start ), 
			 | 
		
		
	
		
			
			| 
				231
			 | 
			
				
			 | 
			
			
				
				-				       desc.end - block ); 
			 | 
		
		
	
		
			
			| 
				232
			 | 
			
				
			 | 
			
			
				
				-		} else { 
			 | 
		
		
	
		
			
			| 
				233
			 | 
			
				
			 | 
			
			
				
				-			/* Block is outside the data area */ 
			 | 
		
		
	
		
			
			| 
				234
			 | 
			
				
			 | 
			
			
				
				-			prev_block = block; 
			 | 
		
		
	
		
			
			| 
				235
			 | 
			
				
			 | 
			
			
				
				-		} 
			 | 
		
		
	
		
			
			| 
				236
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				237
			 | 
			
				
			 | 
			
			
				
				-		/* Move to next free block */ 
			 | 
		
		
	
		
			
			| 
				238
			 | 
			
				
			 | 
			
			
				
				-		block = desc.next_free; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				153
			 | 
			
			
				
				+	/* Find 'before' and 'after' blocks, if any */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				154
			 | 
			
			
				
				+	before.start = before.end = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				155
			 | 
			
			
				
				+	after.start = after.end = buffer->end; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				156
			 | 
			
			
				
				+	block.next = buffer->start + buffer->fill; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				157
			 | 
			
			
				
				+	while ( next_free_block ( &block, buffer ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				158
			 | 
			
			
				
				+		if ( ( block.start < data_start ) && 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				159
			 | 
			
			
				
				+		     ( block.start >= before.start ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				160
			 | 
			
			
				
				+			memcpy ( &before, &block, sizeof ( before ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				161
			 | 
			
			
				
				+		if ( ( block.end > data_end ) && 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				162
			 | 
			
			
				
				+		     ( block.end <= after.end ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				163
			 | 
			
			
				
				+			memcpy ( &after, &block, sizeof ( after ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				164
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				165
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				166
			 | 
			
			
				
				+	/* Truncate 'before' and 'after' blocks around data. */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				167
			 | 
			
			
				
				+	if ( data_start < before.end ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				168
			 | 
			
			
				
				+		before.end = data_start; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				169
			 | 
			
			
				
				+	if ( data_end > after.start ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				170
			 | 
			
			
				
				+		after.start = data_end; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				171
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				172
			 | 
			
			
				
				+	/* Link 'after' block to 'before' block */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				173
			 | 
			
			
				
				+	before.next = after.start; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				174
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				175
			 | 
			
			
				
				+	/* Write back 'before' block, if any */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				176
			 | 
			
			
				
				+	if ( before.start ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				177
			 | 
			
			
				
				+		before.tail = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				178
			 | 
			
			
				
				+		store_free_block ( &before ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				179
			 | 
			
			
				
				+	} else { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				180
			 | 
			
			
				
				+		buffer->fill = before.next - buffer->start; 
			 | 
		
		
	
		
			
			| 
				239
			 | 
			
				181
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				240
			 | 
			
				182
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				183
			 | 
			
			
				
				+	/* Write back 'after' block, if any */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				184
			 | 
			
			
				
				+	if ( after.start < buffer->end ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				185
			 | 
			
			
				
				+		store_free_block ( &after ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				186
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				187
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				188
			 | 
			
			
				
				+	DBG ( "BUFFER [%x,%x) before [%x,%x) after [%x,%x)\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				189
			 | 
			
			
				
				+	      buffer->start, buffer->end, before.start, before.end, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				190
			 | 
			
			
				
				+	      after.start, after.end ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				191
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				192
			 | 
			
			
				
				+	/* Copy data into buffer */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				193
			 | 
			
			
				
				+	copy_to_phys ( data_start, data, len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				194
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				241
			 | 
			
				195
			 | 
			
			
				
				 	DBG ( "BUFFER [%x,%x) full up to %x\n", 
			 | 
		
		
	
		
			
			| 
				242
			 | 
			
				196
			 | 
			
			
				
				 	      buffer->start, buffer->end, buffer->start + buffer->fill ); 
			 | 
		
		
	
		
			
			| 
				243
			 | 
			
				197
			 | 
			
			
				
				  
			 |