|
@@ -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);
|