xref: /haiku/src/add-ons/kernel/bus_managers/pci/pci_module.cpp (revision dd2a1e350b303b855a50fd64e6cb55618be1ae6a)
1 /*
2  * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Copyright 2003, Marcus Overhagen. All rights reserved.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 
8 
9 #include <PCI.h>
10 #include "pci_msi.h"
11 
12 #include "pci_private.h"
13 #include "pci_info.h"
14 #include "pci.h"
15 
16 #define CHECK_RET(err) {status_t _err = (err); if (_err < B_OK) return _err;}
17 
18 
19 device_manager_info *gDeviceManager;
20 
21 
22 static int32
23 pci_old_module_std_ops(int32 op, ...)
24 {
25 	switch (op) {
26 		case B_MODULE_INIT:
27 		{
28 			status_t status;
29 
30 			TRACE(("PCI: pci_module_init\n"));
31 
32 			status = pci_init();
33 			if (status < B_OK)
34 				return status;
35 
36 			pci_print_info();
37 
38 			return B_OK;
39 		}
40 
41 		case B_MODULE_UNINIT:
42 			TRACE(("PCI: pci_module_uninit\n"));
43 			pci_uninit();
44 			return B_OK;
45 	}
46 
47 	return B_BAD_VALUE;
48 }
49 
50 
51 static status_t
52 ResolveBDF(uint8 virtualBus, uint8 device, uint8 function, PCIDev*& dev)
53 {
54 	uint8 bus;
55 	uint8 domain;
56 	status_t result = gPCI->ResolveVirtualBus(virtualBus, &domain, &bus);
57 	if (result != B_OK)
58 		return result;
59 
60 	dev = gPCI->FindDevice(domain, bus, device, function);
61 	if (dev == NULL)
62 		return B_ERROR;
63 
64 	return B_OK;
65 }
66 
67 
68 static struct pci_module_info sOldPCIModule = {
69 	{
70 		{
71 			B_PCI_MODULE_NAME,
72 			B_KEEP_LOADED,
73 			pci_old_module_std_ops
74 		},
75 		NULL
76 	},
77 	.read_io_8 = pci_read_io_8,
78 	.write_io_8 = pci_write_io_8,
79 	.read_io_16 = pci_read_io_16,
80 	.write_io_16 = pci_write_io_16,
81 	.read_io_32 = pci_read_io_32,
82 	.write_io_32 = pci_write_io_32,
83 	.get_nth_pci_info = pci_get_nth_pci_info,
84 	.read_pci_config = pci_read_config,
85 	.write_pci_config = pci_write_config,
86 	.ram_address = pci_ram_address,
87 	.find_pci_capability = pci_find_capability,
88 	.reserve_device = pci_reserve_device,
89 	.unreserve_device = pci_unreserve_device,
90 	.update_interrupt_line = pci_update_interrupt_line,
91 	.find_pci_extended_capability = pci_find_extended_capability,
92 	.get_powerstate = pci_get_powerstate,
93 	.set_powerstate = pci_set_powerstate,
94 
95 	.get_msi_count = [](uint8 bus, uint8 device, uint8 function) {
96 		PCIDev* dev;
97 		if (ResolveBDF(bus, device, function, dev) < B_OK)
98 			return (uint32)0;
99 		return gPCI->GetMSICount(dev);
100 	},
101 	.configure_msi = [](uint8 bus, uint8 device, uint8 function, uint32 count,
102 			uint32 *startVector) {
103 		PCIDev* dev;
104 		CHECK_RET(ResolveBDF(bus, device, function, dev));
105 		return gPCI->ConfigureMSI(dev, count, startVector);
106 	},
107 	.unconfigure_msi = [](uint8 bus, uint8 device, uint8 function) {
108 		PCIDev* dev;
109 		CHECK_RET(ResolveBDF(bus, device, function, dev));
110 		return gPCI->UnconfigureMSI(dev);
111 	},
112 	.enable_msi = [](uint8 bus, uint8 device, uint8 function) {
113 		PCIDev* dev;
114 		CHECK_RET(ResolveBDF(bus, device, function, dev));
115 		return gPCI->EnableMSI(dev);
116 	},
117 	.disable_msi = [](uint8 bus, uint8 device, uint8 function) {
118 		PCIDev* dev;
119 		CHECK_RET(ResolveBDF(bus, device, function, dev));
120 		return gPCI->DisableMSI(dev);
121 	},
122 	.get_msix_count = [](uint8 bus, uint8 device, uint8 function) {
123 		PCIDev* dev;
124 		if (ResolveBDF(bus, device, function, dev) < B_OK)
125 			return (uint32)0;
126 		return gPCI->GetMSIXCount(dev);
127 	},
128 	.configure_msix = [](uint8 bus, uint8 device, uint8 function, uint32 count,
129 			uint32 *startVector) {
130 		PCIDev* dev;
131 		CHECK_RET(ResolveBDF(bus, device, function, dev));
132 		return gPCI->ConfigureMSIX(dev, count, startVector);
133 	},
134 	.enable_msix = [](uint8 bus, uint8 device, uint8 function) {
135 		PCIDev* dev;
136 		CHECK_RET(ResolveBDF(bus, device, function, dev));
137 		return gPCI->EnableMSIX(dev);
138 	}
139 };
140 
141 
142 module_dependency module_dependencies[] = {
143 	{B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager},
144 	{}
145 };
146 
147 driver_module_info gPCILegacyDriverModule = {
148 	{
149 		PCI_LEGACY_DRIVER_MODULE_NAME,
150 		0,
151 		NULL,
152 	},
153 	NULL
154 };
155 
156 module_info *modules[] = {
157 	(module_info *)&sOldPCIModule,
158 	(module_info *)&gPCIRootModule,
159 	(module_info *)&gPCIDeviceModule,
160 	(module_info *)&gPCILegacyDriverModule,
161 	NULL
162 };
163