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
19device_manager_info *gDeviceManager;
20
21
22static int32
23pci_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
51static status_t
52ResolveBDF(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
68static 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
142module_dependency module_dependencies[] = {
143	{B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager},
144	{}
145};
146
147driver_module_info gPCILegacyDriverModule = {
148	{
149		PCI_LEGACY_DRIVER_MODULE_NAME,
150		0,
151		NULL,
152	},
153	NULL
154};
155
156module_info *modules[] = {
157	(module_info *)&sOldPCIModule,
158	(module_info *)&gPCIRootModule,
159	(module_info *)&gPCIDeviceModule,
160	(module_info *)&gPCILegacyDriverModule,
161	NULL
162};
163