1 #include <hal/ahci/ahci.h>
2 #include <hal/ahci/sata.h>
3 #include <asm-generic/isrm.h>
4 #include <lunaix/mm/valloc.h>
5 #include <lunaix/syslog.h>
10 ahci_hba_isr(irq_t irq, const struct hart_state* hstate)
13 struct ahci_driver *pos, *n;
14 struct llist_header* ahcis;
16 ahcis = irq_payload(irq, struct llist_header);
17 llist_for_each(pos, n, ahcis, ahci_drvs)
19 if (pos->id == hart_vector_stamp(hstate)) {
28 // ignore spurious interrupt
29 if (!hba->base[HBA_RIS])
32 u32_t port_num = msbiti - clz(hba->base[HBA_RIS]);
33 struct hba_port* port = hba->ports[port_num];
34 struct hba_cmd_context* cmdctx = &port->cmdctx;
35 u32_t processed = port->regs[HBA_RPxCI] ^ cmdctx->tracked_ci;
37 sata_read_error(port);
39 // FIXME When error occurs, CI will not change. Need error recovery!
41 if (port->regs[HBA_RPxIS] & HBA_FATAL) {
42 // TODO perform error recovery
43 // This should include:
44 // 1. Discard all issued (but pending) requests (signaled as
47 // Complete steps refer to AHCI spec 6.2.2.1
52 u32_t slot = msbiti - clz(processed);
53 struct hba_cmd_state* cmdstate = cmdctx->issued[slot];
59 struct blkio_req* ioreq = (struct blkio_req*)cmdstate->state_ctx;
61 if ((port->device->last_result.status & HBA_PxTFD_ERR)) {
62 ioreq->errcode = port->regs[HBA_RPxTFD] & 0xffff;
63 ioreq->flags |= BLKIO_ERROR;
64 hba_clear_reg(port->regs[HBA_RPxSERR]);
67 blkio_schedule(ioreq->io_ctx);
68 blkio_complete(ioreq);
69 vfree_dma(cmdstate->cmd_table);
72 hba_clear_reg(port->regs[HBA_RPxIS]);
73 hba->base[HBA_RIS] &= ~(1 << (31 - port_num));
77 __ahci_blkio_handler(struct blkio_req* req)
79 struct hba_device* hbadev = (struct hba_device*)req->io_ctx->driver;
81 hbadev->ops.submit(hbadev, req);