xref: /haiku/src/add-ons/kernel/bus_managers/pci/pci_device.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
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 uint8
25 pci_device_read_io_8(pci_device* device, addr_t mappedIOAddress)
26 {
27 	return pci_read_io_8(mappedIOAddress);
28 }
29 
30 
31 static void
32 pci_device_write_io_8(pci_device* device, addr_t mappedIOAddress,
33 	uint8 value)
34 {
35 	pci_write_io_8(mappedIOAddress, value);
36 }
37 
38 
39 static uint16
40 pci_device_read_io_16(pci_device* device, addr_t mappedIOAddress)
41 {
42 	return pci_read_io_16(mappedIOAddress);
43 }
44 
45 
46 static void
47 pci_device_write_io_16(pci_device* device, addr_t mappedIOAddress,
48 	uint16 value)
49 {
50 	pci_write_io_16(mappedIOAddress, value);
51 }
52 
53 
54 static uint32
55 pci_device_read_io_32(pci_device* device, addr_t mappedIOAddress)
56 {
57 	return pci_read_io_32(mappedIOAddress);
58 }
59 
60 
61 static void
62 pci_device_write_io_32(pci_device* device, addr_t mappedIOAddress, uint32 value)
63 {
64 	pci_write_io_32(mappedIOAddress, value);
65 }
66 
67 
68 static uint32
69 pci_device_read_pci_config(pci_device* device, uint16 offset, uint8 size)
70 {
71 	return gPCI->ReadConfig(device->device, offset, size);
72 }
73 
74 
75 static void
76 pci_device_write_pci_config(pci_device* device, uint16 offset, uint8 size,
77 	uint32 value)
78 {
79 	gPCI->WriteConfig(device->device, offset, size, value);
80 }
81 
82 
83 static phys_addr_t
84 pci_device_ram_address(pci_device* device, phys_addr_t physicalAddress)
85 {
86 	return pci_ram_address(physicalAddress);
87 }
88 
89 
90 static status_t
91 pci_device_find_capability(pci_device* device, uint8 capID, uint8* offset)
92 {
93 	return gPCI->FindCapability(device->device, capID, offset);
94 }
95 
96 
97 static status_t
98 pci_device_find_extended_capability(pci_device* device, uint16 capID,
99 	uint16* offset)
100 {
101 	return gPCI->FindExtendedCapability(device->device, capID, offset);
102 }
103 
104 
105 static uint8
106 pci_device_get_powerstate(pci_device *device)
107 {
108 	return gPCI->GetPowerstate(device->device);
109 }
110 
111 
112 static void
113 pci_device_set_powerstate(pci_device *device, uint8 state)
114 {
115 	return gPCI->SetPowerstate(device->device, state);
116 }
117 
118 
119 static void
120 pci_device_get_pci_info(pci_device* device, struct pci_info* info)
121 {
122 	if (info == NULL)
123 		return;
124 
125 	*info = device->device->info;
126 }
127 
128 
129 static status_t
130 pci_device_init_driver(device_node* node, void** _cookie)
131 {
132 	uint8 domain;
133 	uint8 bus, deviceNumber, function;
134 	if (gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_DOMAIN, &domain,
135 			false) != B_OK
136 		|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_BUS, &bus,
137 			false) != B_OK
138 		|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_DEVICE,
139 			&deviceNumber, false) != B_OK
140 		|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_FUNCTION,
141 			&function, false) != B_OK)
142 		return B_ERROR;
143 
144 	PCIDev *dev = gPCI->FindDevice(domain, bus, deviceNumber, function);
145 	if (dev == NULL) {
146 		panic("device not found!\n");
147 		return ENODEV;
148 	}
149 
150 	pci_device* device = (pci_device*)malloc(sizeof(*device));
151 	if (device == NULL)
152 		return B_NO_MEMORY;
153 
154 	device->device = dev;
155 	device->node = node;
156 
157 	*_cookie = device;
158 	return B_OK;
159 }
160 
161 
162 static void
163 pci_device_uninit_driver(void* cookie)
164 {
165 	pci_device* device = (pci_device*)cookie;
166 	free(device);
167 }
168 
169 
170 static status_t
171 pci_device_std_ops(int32 op, ...)
172 {
173 	switch (op) {
174 		case B_MODULE_INIT:
175 		case B_MODULE_UNINIT:
176 			return B_OK;
177 	}
178 
179 	return B_BAD_VALUE;
180 }
181 
182 
183 pci_device_module_info gPCIDeviceModule = {
184 	{
185 		{
186 			PCI_DEVICE_MODULE_NAME,
187 			0,
188 			pci_device_std_ops
189 		},
190 
191 		NULL,		// supports device
192 		NULL,		// register device (our parent registered us)
193 		pci_device_init_driver,
194 		pci_device_uninit_driver,
195 		NULL,		// register child devices
196 		NULL,		// rescan devices
197 		NULL,		// device removed
198 	},
199 
200 	pci_device_read_io_8,
201 	pci_device_write_io_8,
202 	pci_device_read_io_16,
203 	pci_device_write_io_16,
204 	pci_device_read_io_32,
205 	pci_device_write_io_32,
206 
207 	pci_device_ram_address,
208 
209 	pci_device_read_pci_config,
210 	pci_device_write_pci_config,
211 	pci_device_find_capability,
212 	pci_device_get_pci_info,
213 	pci_device_find_extended_capability,
214 	pci_device_get_powerstate,
215 	pci_device_set_powerstate
216 };
217