| 
					
				 | 
			
			
				@@ -324,7 +324,9 @@ static void floppy_end_command(void *ack, unsigned int ack_len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    unsigned int idx, nr_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unsigned int nr_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unsigned int max_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    time_t deadline; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } read; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void _write_28bit(uint32_t x) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -342,7 +344,7 @@ static void rdata_encode_flux(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     timcnt_t prev = dma.prev_sample, curr, next; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t ticks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ASSERT(read.idx < read.nr_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ASSERT(read.nr_index < read.max_index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* We don't want to race the Index IRQ handler. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     IRQ_global_disable(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -350,10 +352,10 @@ static void rdata_encode_flux(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* Find out where the DMA engine's producer index has got to. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     prod = ARRAY_SIZE(dma.buf) - dma_rdata.ndtr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (read.idx != index.count) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (read.nr_index != index.count) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /* We have just passed the index mark: Record information about  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          * the just-completed revolution. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        read.idx = index.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        read.nr_index = index.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ticks = (timcnt_t)(index.rdata_cnt - prev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         IRQ_global_enable(); /* we're done reading ISR variables */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         u_buf[U_MASK(u_prod++)] = 0xff; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -415,9 +417,6 @@ static void rdata_encode_flux(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static uint8_t floppy_read_prep(const struct gw_read_flux *rf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (rf->nr_idx == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return ACK_BAD_COMMAND; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* Prepare Timer & DMA. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     dma_rdata.mar = (uint32_t)(unsigned long)dma.buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     dma_rdata.ndtr = ARRAY_SIZE(dma.buf);     
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -437,7 +436,9 @@ static uint8_t floppy_read_prep(const struct gw_read_flux *rf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     flux_op.start = time_now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     flux_op.status = ACK_OKAY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     memset(&read, 0, sizeof(read)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    read.nr_idx = rf->nr_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    read.max_index = rf->max_index ?: INT_MAX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    read.deadline = flux_op.start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    read.deadline += rf->ticks ? time_from_samples(rf->ticks) : INT_MAX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return ACK_OKAY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -476,9 +477,10 @@ static void floppy_read(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             floppy_state = ST_read_flux_drain; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             u_cons = u_prod = avail = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (read.idx >= read.nr_idx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if ((read.nr_index >= read.max_index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   || (time_since(read.deadline) >= 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            /* Read all requested revolutions. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            /* Read all requested data. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             floppy_flux_end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             floppy_state = ST_read_flux_drain; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -523,6 +525,7 @@ static void floppy_read(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     bool_t is_finished; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bool_t cue_at_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     bool_t terminate_at_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t astable_period; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t ticks; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -745,6 +748,7 @@ static uint8_t floppy_write_prep(const struct gw_write_flux *wf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     flux_op.status = ACK_OKAY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     memset(&write, 0, sizeof(write)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     write.flux_mode = FLUXMODE_idle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    write.cue_at_index = wf->cue_at_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     write.terminate_at_index = wf->terminate_at_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return ACK_OKAY; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -792,7 +796,7 @@ static void floppy_write_wait_data(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void floppy_write_wait_index(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (index.count == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (write.cue_at_index && (index.count == 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (time_since(flux_op.start) > time_ms(2000)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             /* Timeout */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             floppy_flux_end(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -900,7 +904,7 @@ static uint8_t floppy_erase_prep(const struct gw_erase_flux *ef) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     floppy_state = ST_erase_flux; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     flux_op.status = ACK_OKAY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    flux_op.end = time_now() + time_from_samples(ef->erase_ticks); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    flux_op.end = time_now() + time_from_samples(ef->ticks); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return ACK_OKAY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1145,16 +1149,18 @@ static void process_command(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case CMD_READ_FLUX: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        struct gw_read_flux rf = { .nr_idx = 2 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if ((len < 2) || (len > (2 + sizeof(rf)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        struct gw_read_flux rf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (len != (2 + sizeof(rf))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             goto bad_command; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         memcpy(&rf, &u_buf[2], len-2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         u_buf[1] = floppy_read_prep(&rf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case CMD_WRITE_FLUX: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        struct gw_write_flux wf = { 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if ((len < 2) || (len > (2 + sizeof(wf)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        struct gw_write_flux wf = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .cue_at_index = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .terminate_at_index = 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (len != (2 + sizeof(wf))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             goto bad_command; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         memcpy(&wf, &u_buf[2], len-2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         u_buf[1] = floppy_write_prep(&wf); 
			 |