xref: /minix/minix/lib/libddekit/src/pci.c (revision 83133719)
1 /**
2  * pci.c
3  * @author: Dirk Vogt
4  * @date: 2010-02-18
5  */
6 
7 #include "common.h"
8 
9 #include <ddekit/pci.h>
10 #include <ddekit/panic.h>
11 #include <minix/syslib.h>
12 
13 #ifdef DDEBUG_LEVEL_PCI
14 #undef DDEBUG
15 #define DDEBUG DDEBUG_LEVEL_PCI
16 #endif
17 
18 #include "util.h"
19 #include "debug.h"
20 
21 #define PCI_MAX_DEVS 32
22 
23 #define PCI_TAKE_ALL (-1)
24 
25 struct ddekit_pci_dev {
26 	int devind; /* thats how we identify the defice at the pci server */
27 	ddekit_uint16_t vid; /* as we get them for                 */
28 	                     /*   free during iteration store them */
29 	ddekit_uint16_t did;
30 	int bus;
31 	int slot; /* slot should equal index in dev array */
32 	int func; /* don't support multiple functionalities yet -> 0 */
33 };
34 
35 struct ddekit_pci_dev pci_devs[PCI_MAX_DEVS];
36 
37 static struct ddekit_pci_dev * ddekit_get_dev_helper(int bus, int slot,
38 	int func);
39 
40 /****************************************************************************/
41 /*      ddekit_pci_init_only_one                                            */
42 /****************************************************************************/
43 void ddekit_pci_init_only_one(int skip)
44 {
45 	/*
46 	 * If skip is not PCI_TAKE_ALL this function will skip skip PCI DEVICES
47 	 * and than only take on PCI device.
48 	 */
49 
50 	int res, count, more, take_all = 0;
51 
52 	if (skip == -1) {
53 		take_all = 1;
54 	}
55 
56 	DDEBUG_MSG_INFO("Initializing PCI subsystem...");
57 
58 	pci_init();
59 
60 	/*
61 	 * Iterate the PCI-bus
62 	 */
63 
64 	more = 1;
65 
66 	for (count = 0 ; count < PCI_MAX_DEVS ; count++) {
67 
68 		struct ddekit_pci_dev *d = &pci_devs[count];
69 
70 		if (more) {
71 			if ( count==0 ) {
72 				res = pci_first_dev(&d->devind, &d->vid, &d->did);
73 			} else {
74 				d->devind = pci_devs[count-1].devind;
75 				res = pci_next_dev(&d->devind, &d->vid, &d->did);
76 			}
77 
78 			if (res && d->devind!=0 && (take_all || skip == 0)) {
79 
80 				DDEBUG_MSG_VERBOSE("Found pci device: "
81 				                   "(ind: %x, vid: %x, did: %x) "
82 							 	   "mapped to slot %x",
83 								   d->devind, d->vid, d->did, count);
84 				d->slot = count;
85 				d->bus  = 0;
86 				d->func = 0;
87 				res = pci_reserve_ok(d->devind);
88 				if (res != 0) {
89 					ddekit_panic("ddekit_pci_init_only_one: "
90 					             "pci_reserve_ok failed (%d)\n",res);
91 				}
92 
93 			} else {
94 				/* no more PCI devices */
95 				DDEBUG_MSG_VERBOSE("Found %d PCI devices.", count);
96 				d->devind = -1;
97 				more = 0;
98 			} /*if (res) */
99 		} else {
100 			d->devind = -1;
101 		}
102 		if (!take_all) {
103 			skip--;
104 		}
105 	}
106 }
107 
108 /****************************************************************************/
109 /*      ddekit_pci_get_device_id                                            */
110 /****************************************************************************/
111 void ddekit_pci_init(void)
112 {
113 	ddekit_pci_init_only_one(DDEKIT_PCI_ANY_ID);
114 }
115 
116 /****************************************************************************/
117 /*      ddekit_pci_get_device_id                                            */
118 /****************************************************************************/
119 int ddekit_pci_get_device(int nr, int *bus, int *slot, int *func)
120 {
121 	if(nr >= 0  && nr < PCI_MAX_DEVS) {
122 
123 		*bus = 0;
124 		*slot = nr;
125 		*func =0;
126 
127 		return 0;
128 	}
129 
130 	return -1;
131 }
132 
133 /****************************************************************************/
134 /*      ddekit_pci_get_device_id                                            */
135 /****************************************************************************/
136 static struct ddekit_pci_dev *
137 ddekit_get_dev_helper(int bus, int slot, int func)
138 {
139 	/*
140 	 * Used internally to look up devices.
141 	 * Should make it easier to support multiple buses somewhen
142 	 */
143 	struct ddekit_pci_dev * ret = 0;
144 	if (slot >= 0  && slot < PCI_MAX_DEVS) {
145 		ret = &pci_devs[slot];
146 	}
147 	if (ret->devind == -1) {
148 		ret = 0;
149 	}
150 	return ret;
151 }
152 
153 /****************************************************************************/
154 /*      ddekit_pci_read                                                     */
155 /****************************************************************************/
156 int ddekit_pci_read
157 (int bus, int slot, int func, int pos, int len, ddekit_uint32_t *val)
158 {
159 	switch(len) {
160 		case 1:
161 			return ddekit_pci_readb(bus, slot, func, pos,
162 			    (ddekit_uint8_t*)  val);
163 		case 2:
164 			return ddekit_pci_readw(bus, slot, func, pos,
165 			    (ddekit_uint16_t*) val);
166 		case 4:
167 			return ddekit_pci_readl(bus, slot, func, pos, val);
168 		default: return -1;
169 	}
170 }
171 
172 /****************************************************************************/
173 /*      ddekit_pci_write                                                    */
174 /****************************************************************************/
175 int ddekit_pci_write
176 (int bus, int slot, int func, int pos, int len, ddekit_uint32_t val)
177 {
178 	switch(len) {
179 		case 1:
180 			return ddekit_pci_writeb(bus, slot, func, pos,
181 			    (ddekit_uint8_t)  val);
182 		case 2:
183 			return ddekit_pci_writew(bus, slot, func, pos,
184 			    (ddekit_uint16_t) val);
185 		case 4:
186 			return ddekit_pci_writel(bus, slot, func, pos, val);
187 		default: return -1;
188 	}
189 }
190 
191 /****************************************************************************/
192 /*      ddekit_pci_readb                                                    */
193 /****************************************************************************/
194 int ddekit_pci_readb (int bus, int slot, int func, int pos, ddekit_uint8_t  *val) {
195 	struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
196 	if (func!=0) {
197 		*val=0;
198 		return 0;
199 	}
200 	if (dev) {
201 		*val = pci_attr_r8 (dev->devind, pos);
202 		DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
203 		    bus, slot, func, pos, *val);
204 		return 0;
205 	}
206 	return -1;
207 }
208 
209 /****************************************************************************/
210 /*      ddekit_pci_readw                                                    */
211 /****************************************************************************/
212 int ddekit_pci_readw
213 (int bus, int slot, int func, int pos, ddekit_uint16_t *val) {
214 	struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
215 	if (func!=0) {
216 		*val=0;
217 		return 0;
218 	}
219 	if (dev) {
220 		*val = pci_attr_r16 (dev->devind, pos);
221 		DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
222 		    bus, slot, func, pos, *val);
223 		return 0;
224 	}
225 	return -1;
226 }
227 
228 /****************************************************************************/
229 /*      ddekit_pci_readl                                                    */
230 /****************************************************************************/
231 int ddekit_pci_readl
232 (int bus, int slot, int func, int pos, ddekit_uint32_t *val)  {
233 	struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
234 	if (func!=0) {
235 		*val=0;
236 		return 0;
237 	}
238 	if (dev) {
239 		*val = pci_attr_r32 (dev->devind, pos);
240 		DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
241 		    bus, slot, func, pos, *val);
242 		return 0;
243 	}
244 	return -1;
245 }
246 
247 /****************************************************************************/
248 /*      ddekit_pci_writeb                                                   */
249 /****************************************************************************/
250 int ddekit_pci_writeb
251 (int bus, int slot, int func, int pos, ddekit_uint8_t val) {
252 	struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
253 	if (dev) {
254 		pci_attr_w8 (dev->devind, pos, val);
255 		DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
256 		    bus, slot, func, pos, val);
257 		return 0;
258 	}
259 	return -1;
260 }
261 
262 /****************************************************************************/
263 /*      ddekit_pci_writel                                                   */
264 /****************************************************************************/
265 int ddekit_pci_writew
266 (int bus, int slot, int func, int pos, ddekit_uint16_t val) {
267 	struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
268 	if (dev) {
269 		pci_attr_w16 (dev->devind, pos, val);
270 		DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
271 		    bus,slot,func,pos, val);
272 		return 0;
273 	}
274 	return -1;
275 }
276 
277 /****************************************************************************/
278 /*      ddekit_pci_writel                                                   */
279 /****************************************************************************/
280 int ddekit_pci_writel
281 (int bus, int slot, int func, int pos, ddekit_uint32_t val) {
282 	struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
283 	if (dev) {
284 		pci_attr_w32 (dev->devind, pos, val);
285 		DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",bus,slot,func,pos, val);
286 		return 0;
287 	}
288 	return -1;
289 }
290 
291 /****************************************************************************/
292 /*      ddekit_pci_find_device                                              */
293 /****************************************************************************/
294 struct ddekit_pci_dev *ddekit_pci_find_device
295 (int *bus, int *slot, int *func, struct ddekit_pci_dev *start)
296 {
297 	int i,search=0;
298 
299 	if(start)
300 		search = 1;
301 
302 	for(i=0; i < PCI_MAX_DEVS ; i++)
303 	{
304 		/* start searching? */
305 		if (search)
306 			search = (&pci_devs[i]==start);
307 		else
308 		{
309 			struct ddekit_pci_dev * dev = &pci_devs[i];
310 			if ((*slot==dev->slot || *slot == DDEKIT_PCI_ANY_ID)
311 				&& (*func==dev->func || *func == DDEKIT_PCI_ANY_ID))
312 			{
313 				*bus  = 0;
314 				*slot = dev->slot;
315 				*func = dev->func;
316 				return dev;
317 			}
318 		}
319 	}
320 	return 0;
321 }
322 
323 /****************************************************************************/
324 /*      ddekit_pci_get_vendor                                               */
325 /****************************************************************************/
326 unsigned short ddekit_pci_get_vendor(struct ddekit_pci_dev *dev)
327 {
328 	return dev->vid;
329 }
330 
331 /****************************************************************************/
332 /*      ddekit_pci_get_device_id                                            */
333 /****************************************************************************/
334 unsigned short ddekit_pci_get_device_id(struct ddekit_pci_dev *dev)
335 {
336 	return dev->did;
337 }
338 
339 /*
340  * XXX: Those are neither used be DDEFBSD or DDELinux implement them
341  *      when you need them
342  */
343 
344 /****************************************************************************/
345 /*      ddekit_pci_enable_device                                            */
346 /****************************************************************************/
347 int ddekit_pci_enable_device(struct ddekit_pci_dev *dev)
348 {
349 	WARN_UNIMPL;
350 	return 0;
351 }
352 
353 /****************************************************************************/
354 /*      ddekit_pci_disable_device                                           */
355 /****************************************************************************/
356 int ddekit_pci_disable_device(struct ddekit_pci_dev *dev)
357 {
358 	WARN_UNIMPL;
359 	return 0;
360 }
361 
362 /****************************************************************************/
363 /*      ddekit_pci_set_master                                               */
364 /****************************************************************************/
365 void ddekit_pci_set_master(struct ddekit_pci_dev *dev)
366 {
367 	WARN_UNIMPL;
368 }
369 
370 
371 /****************************************************************************/
372 /*      ddekit_pci_get_sub_vendor                                           */
373 /****************************************************************************/
374 unsigned short ddekit_pci_get_sub_vendor(struct ddekit_pci_dev *dev)
375 {
376 	WARN_UNIMPL;
377 	return 0;
378 }
379 
380 /****************************************************************************/
381 /*      ddekit_pci_get_sub_device                                           */
382 /****************************************************************************/
383 unsigned short ddekit_pci_get_sub_device(struct ddekit_pci_dev *dev)
384 {
385 	WARN_UNIMPL;
386 	return 0;
387 }
388 
389 /****************************************************************************/
390 /*      ddekit_pci_get_dev_class                                            */
391 /****************************************************************************/
392 unsigned ddekit_pci_get_dev_class(struct ddekit_pci_dev *dev)
393 {
394 	WARN_UNIMPL;
395 	return 0;
396 }
397 
398 /****************************************************************************/
399 /*      ddekit_pci_get_irq                                                  */
400 /****************************************************************************/
401 unsigned long
402 ddekit_pci_get_irq(struct ddekit_pci_dev *dev)
403 {
404 	WARN_UNIMPL;
405 	return 0;
406 }
407 
408 /****************************************************************************/
409 /*      ddekit_pci_get_name                                                 */
410 /****************************************************************************/
411 char *ddekit_pci_get_name(struct ddekit_pci_dev *dev)
412 {
413 	WARN_UNIMPL;
414 	return 0;
415 }
416 
417 /****************************************************************************/
418 /*      ddekit_pci_get_slot_name                                            */
419 /****************************************************************************/
420 char *ddekit_pci_get_slot_name(struct ddekit_pci_dev *dev)
421 {
422 	WARN_UNIMPL;
423 	return 0;
424 }
425 
426 /****************************************************************************/
427 /*      ddekit_pci_get_resource                                             */
428 /****************************************************************************/
429 ddekit_pci_res_t *
430 ddekit_pci_get_resource(struct ddekit_pci_dev *dev, unsigned int idx)
431 {
432 	WARN_UNIMPL;
433 	return 0;
434 }
435 
436 /****************************************************************************/
437 /*      ddekit_pci_irq_enable                                               */
438 /****************************************************************************/
439 int ddekit_pci_irq_enable
440 (int bus, int slot, int func, int pin, int *irq)
441 {
442 	/* call not needed */
443 #if 0
444 	WARN_UNIMPL;
445 #endif
446 	return 0;
447 }
448 
449