dma_cb(s, 0);
}
+static void ahci_restart_dma(IDEDMA *dma)
+{
+ /* Nothing to do, ahci_start_dma already resets s->io_buffer_offset. */
+}
+
/**
* Called in DMA R/W chains to read the PRDT, utilizing ahci_populate_sglist.
* Not currently invoked by PIO R/W chains,
static const IDEDMAOps ahci_dma_ops = {
.start_dma = ahci_start_dma,
+ .restart_dma = ahci_restart_dma,
.start_transfer = ahci_start_transfer,
.prepare_buf = ahci_dma_prepare_buf,
.commit_buf = ahci_commit_buf,
ad->port_no = i;
ad->port.dma = &ad->dma;
ad->port.dma->ops = &ahci_dma_ops;
+ ide_register_restart_cb(&ad->port);
}
}
map_page(s->as, &ad->res_fis,
((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
/*
- * All pending i/o should be flushed out on a migrate. However,
- * we might not have cleared the busy_slot since this is done
- * in a bh. Also, issue i/o against any slots that are pending.
+ * If an error is present, ad->busy_slot will be valid and not -1.
+ * In this case, an operation is waiting to resume and will re-check
+ * for additional AHCI commands to execute upon completion.
+ *
+ * In the case where no error was present, busy_slot will be -1,
+ * and we should check to see if there are additional commands waiting.
*/
- if ((ad->busy_slot != -1) &&
- !(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) {
- pr->cmd_issue &= ~(1 << ad->busy_slot);
- ad->busy_slot = -1;
+ if (ad->busy_slot == -1) {
+ check_cmd(s, i);
}
- check_cmd(s, i);
}
return 0;