xref: /haiku/src/add-ons/kernel/bus_managers/pci/pci_device.cpp (revision 9f3bdf3d039430b5172c424def20ce5d9f7367d4)
1 /*
2  * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Copyright 2002-2003, Thomas Kurschel. All rights reserved.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "pci.h"
14 #include "pci_private.h"
15 
16 
17 // information about one PCI device
18 struct pci_device {
19 	PCIDev*					device;
20 	device_node*			node;
21 };
22 
23 
24 static status_t
25 pci_device_init_driver(device_node* node, void** _cookie)
26 {
27 	uint8 domain;
28 	uint8 bus, deviceNumber, function;
29 	if (gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_DOMAIN, &domain,
30 			false) != B_OK
31 		|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_BUS, &bus,
32 			false) != B_OK
33 		|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_DEVICE,
34 			&deviceNumber, false) != B_OK
35 		|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_FUNCTION,
36 			&function, false) != B_OK)
37 		return B_ERROR;
38 
39 	PCIDev *dev = gPCI->FindDevice(domain, bus, deviceNumber, function);
40 	if (dev == NULL) {
41 		panic("device not found!\n");
42 		return ENODEV;
43 	}
44 
45 	pci_device* device = (pci_device*)malloc(sizeof(*device));
46 	if (device == NULL)
47 		return B_NO_MEMORY;
48 
49 	device->device = dev;
50 	device->node = node;
51 
52 	*_cookie = device;
53 	return B_OK;
54 }
55 
56 
57 static void
58 pci_device_uninit_driver(void* cookie)
59 {
60 	pci_device* device = (pci_device*)cookie;
61 	free(device);
62 }
63 
64 
65 static status_t
66 pci_device_std_ops(int32 op, ...)
67 {
68 	switch (op) {
69 		case B_MODULE_INIT:
70 		case B_MODULE_UNINIT:
71 			return B_OK;
72 	}
73 
74 	return B_BAD_VALUE;
75 }
76 
77 
78 pci_device_module_info gPCIDeviceModule = {
79 	{
80 		{
81 			PCI_DEVICE_MODULE_NAME,
82 			0,
83 			pci_device_std_ops
84 		},
85 
86 		.init_driver = pci_device_init_driver,
87 		.uninit_driver = pci_device_uninit_driver,
88 	},
89 
90 	.read_io_8 = [](pci_device *device, addr_t mappedIOAddress) {
91 		return pci_read_io_8(mappedIOAddress);
92 	},
93 	.write_io_8 = [](pci_device *device, addr_t mappedIOAddress, uint8 value) {
94 		pci_write_io_8(mappedIOAddress, value);
95 	},
96 	.read_io_16 = [](pci_device *device, addr_t mappedIOAddress) {
97 		return pci_read_io_16(mappedIOAddress);
98 	},
99 	.write_io_16 = [](pci_device *device, addr_t mappedIOAddress, uint16 value) {
100 		pci_write_io_16(mappedIOAddress, value);
101 	},
102 	.read_io_32 = [](pci_device *device, addr_t mappedIOAddress) {
103 		return pci_read_io_32(mappedIOAddress);
104 	},
105 	.write_io_32 = [](pci_device *device, addr_t mappedIOAddress, uint32 value) {
106 		pci_write_io_32(mappedIOAddress, value);
107 	},
108 	.ram_address = [](pci_device *device, phys_addr_t physicalAddress) {
109 		return pci_ram_address(physicalAddress);
110 	},
111 	.read_pci_config = [](pci_device *device, uint16 offset, uint8 size) {
112 		return gPCI->ReadConfig(device->device, offset, size);
113 	},
114 	.write_pci_config = [](pci_device *device, uint16 offset, uint8 size, uint32 value) {
115 		gPCI->WriteConfig(device->device, offset, size, value);
116 	},
117 	.find_pci_capability = [](pci_device *device, uint8 capID, uint8 *offset) {
118 		return gPCI->FindCapability(device->device, capID, offset);
119 	},
120 	.get_pci_info = [](pci_device *device, struct pci_info *info) {
121 		if (info == NULL)
122 			return;
123 		*info = device->device->info;
124 	},
125 	.find_pci_extended_capability = [](pci_device *device, uint16 capID, uint16 *offset) {
126 		return gPCI->FindExtendedCapability(device->device, capID, offset);
127 	},
128 	.get_powerstate = [](pci_device *device) {
129 		return gPCI->GetPowerstate(device->device);
130 	},
131 	.set_powerstate = [](pci_device *device, uint8 state) {
132 		gPCI->SetPowerstate(device->device, state);
133 	},
134 	.get_msi_count = [](pci_device *device) {
135 		return gPCI->GetMSICount(device->device);
136 	},
137 	.configure_msi = [](pci_device *device, uint32 count, uint32 *startVector) {
138 		return gPCI->ConfigureMSI(device->device, count, startVector);
139 	},
140 	.unconfigure_msi = [](pci_device *device) {
141 		return gPCI->UnconfigureMSI(device->device);
142 	},
143 	.enable_msi = [](pci_device *device) {
144 		return gPCI->EnableMSI(device->device);
145 	},
146 	.disable_msi = [](pci_device *device) {
147 		return gPCI->DisableMSI(device->device);
148 	},
149 	.get_msix_count = [](pci_device *device) {
150 		return gPCI->GetMSIXCount(device->device);
151 	},
152 	.configure_msix = [](pci_device *device, uint32 count, uint32 *startVector) {
153 		return gPCI->ConfigureMSIX(device->device, count, startVector);
154 	},
155 	.enable_msix = [](pci_device *device) {
156 		return gPCI->EnableMSIX(device->device);
157 	}
158 };
159