rewrite the device subsystem interfaces (#48)
[lunaix-os.git] / lunaix-os / hal / ahci / ahci_pci.c
1 #include <lunaix/spike.h>
2 #include <lunaix/status.h>
3
4 #include <hal/ahci/ahci.h>
5 #include <hal/pci.h>
6
7 static int
8 ahci_pci_create(struct device_def* def, morph_t* morphed)
9 {
10     struct pci_probe* probe;
11     struct device* dev;
12     struct pci_base_addr* bar6;
13     struct ahci_driver* ahci_drv;
14     msi_vector_t msiv;
15
16     probe = changeling_try_reveal(morphed, pci_probe_morpher);
17     if (!probe) {
18         return EINVAL;
19     }
20
21     bar6 = pci_device_bar(probe, 5);
22     assert_msg(pci_bar_mmio_space(bar6), "AHCI: BAR#6 is not MMIO.");
23
24     pci_reg_t cmd = 0;
25     pci_cmd_set_bus_master(&cmd);
26     pci_cmd_set_mmio(&cmd);
27     pci_cmd_set_msi(&cmd);
28     pci_apply_command(probe, cmd);
29     
30     assert(pci_capability_msi(probe));
31
32     msiv = pci_msi_setup_simple(probe, ahci_hba_isr);
33
34     struct ahci_driver_param param = {
35         .mmio_base = bar6->start,
36         .mmio_size = bar6->size,
37         .ahci_iv = msi_vect(msiv),
38     };
39
40     ahci_drv = ahci_driver_init(&param);
41     dev = device_allocvol(NULL, ahci_drv);
42
43     device_setname(dev_meta(dev), 
44                    "pci-ahci%d", devclass_mkvar(&def->class));
45
46     pci_bind_instance(probe, dev);
47
48     return 0;
49 }
50
51 static bool
52 ahci_pci_compat(struct pci_probe* probe)
53 {
54     return pci_device_class(probe) == AHCI_HBA_CLASS;
55 }
56
57 static int
58 ahci_pci_register(struct device_def* def)
59 {
60     return !pci_register_driver(def, ahci_pci_compat);
61 }
62
63
64 static struct device_def ahcidef = 
65 {
66     def_device_class(GENERIC, STORAGE, SATA),
67     def_device_name("Generic AHCI (pci-bus)"),
68
69     def_on_register(ahci_pci_register),
70     def_on_create(ahci_pci_create),
71
72     def_non_trivial
73 };
74 EXPORT_DEVICE(ahci, &ahcidef, load_postboot);