refactor: make pci device driver loading passive, pci bus scanner will not load them...
[lunaix-os.git] / lunaix-os / hal / ahci / io_event.c
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>
6
7 LOG_MODULE("io_evt")
8
9 void
10 ahci_hba_isr(const isr_param* param)
11 {
12     struct ahci_hba* hba;
13     struct ahci_driver *pos, *n;
14     struct llist_header* ahcis = (struct llist_header*)isrm_get_payload(param);
15
16     llist_for_each(pos, n, ahcis, ahci_drvs)
17     {
18         if (pos->id == (int)param->execp->vector) {
19             hba = &pos->hba;
20             goto proceed;
21         }
22     }
23
24     return;
25
26 proceed:
27     // ignore spurious interrupt
28     if (!hba->base[HBA_RIS])
29         return;
30
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;
35
36     sata_read_error(port);
37
38     // FIXME When error occurs, CI will not change. Need error recovery!
39     if (!processed) {
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
44             //      error)
45             //      2. Restart port
46             // Complete steps refer to AHCI spec 6.2.2.1
47         }
48         goto done;
49     }
50
51     u32_t slot = 31 - __builtin_clz(processed);
52     struct hba_cmd_state* cmdstate = cmdctx->issued[slot];
53
54     if (!cmdstate) {
55         goto done;
56     }
57
58     struct blkio_req* ioreq = (struct blkio_req*)cmdstate->state_ctx;
59
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]);
64     }
65
66     blkio_schedule(ioreq->io_ctx);
67     blkio_complete(ioreq);
68     vfree(cmdstate->cmd_table);
69
70 done:
71     hba_clear_reg(port->regs[HBA_RPxIS]);
72     hba->base[HBA_RIS] &= ~(1 << (31 - port_num));
73 }
74
75 void
76 __ahci_blkio_handler(struct blkio_req* req)
77 {
78     struct hba_device* hbadev = (struct hba_device*)req->io_ctx->driver;
79
80     hbadev->ops.submit(hbadev, req);
81 }