1 #include <hal/ahci/ahci.h>
2 #include <hal/ahci/sata.h>
3 #include <lunaix/isrm.h>
4 #include <lunaix/mm/valloc.h>
5 #include <lunaix/syslog.h>
9 extern struct llist_header ahcis;
12 __ahci_hba_isr(const isr_param* param)
15 struct ahci_driver *pos, *n;
16 llist_for_each(pos, n, &ahcis, ahci_drvs)
18 if (pos->id == param->execp->vector) {
27 // ignore spurious interrupt
28 if (!hba->base[HBA_RIS])
31 u32_t port_num = 31 - __builtin_clz(hba->base[HBA_RIS]);
32 struct hba_port* port = hba->ports[port_num];
33 struct hba_cmd_context* cmdctx = &port->cmdctx;
34 u32_t processed = port->regs[HBA_RPxCI] ^ cmdctx->tracked_ci;
36 sata_read_error(port);
38 // FIXME When error occurs, CI will not change. Need error recovery!
40 if (port->regs[HBA_RPxIS] & HBA_FATAL) {
41 // TODO perform error recovery
42 // This should include:
43 // 1. Discard all issued (but pending) requests (signaled as
46 // Complete steps refer to AHCI spec 6.2.2.1
51 u32_t slot = 31 - __builtin_clz(processed);
52 struct hba_cmd_state* cmdstate = cmdctx->issued[slot];
58 struct blkio_req* ioreq = (struct blkio_req*)cmdstate->state_ctx;
60 if ((port->device->last_result.status & HBA_PxTFD_ERR)) {
61 ioreq->errcode = port->regs[HBA_RPxTFD] & 0xffff;
62 ioreq->flags |= BLKIO_ERROR;
63 hba_clear_reg(port->regs[HBA_RPxSERR]);
66 blkio_schedule(ioreq->io_ctx);
67 blkio_complete(ioreq);
68 vfree(cmdstate->cmd_table);
71 hba_clear_reg(port->regs[HBA_RPxIS]);
72 hba->base[HBA_RIS] &= ~(1 << (31 - port_num));
76 __ahci_blkio_handler(struct blkio_req* req)
78 struct hba_device* hbadev = (struct hba_device*)req->io_ctx->driver;
80 hbadev->ops.submit(hbadev, req);