. pci driver now returns devices, even when they have been pci_reserve()d
[minix3.git] / drivers / pci / main.c
blob9283e46176dd81e69dc4544387f8278998f0bef9
1 /*
2 main.c
3 */
5 #include "../drivers.h"
7 #include <ibm/pci.h>
8 #include <minix/rs.h>
10 #include "pci.h"
12 #define NR_DRIVERS 16
14 PRIVATE struct name
16 char name[M3_STRING];
17 int tasknr;
18 } names[NR_DRIVERS];
20 PRIVATE struct acl
22 int inuse;
23 struct rs_pci acl;
24 } acl[NR_DRIVERS];
26 FORWARD _PROTOTYPE( void do_init, (message *mp) );
27 FORWARD _PROTOTYPE( void do_sig_handler, (void) );
28 FORWARD _PROTOTYPE( void do_first_dev, (message *mp) );
29 FORWARD _PROTOTYPE( void do_next_dev, (message *mp) );
30 FORWARD _PROTOTYPE( void do_find_dev, (message *mp) );
31 FORWARD _PROTOTYPE( void do_ids, (message *mp) );
32 FORWARD _PROTOTYPE( void do_dev_name, (message *mp) );
33 FORWARD _PROTOTYPE( void do_dev_name_s, (message *mp) );
34 FORWARD _PROTOTYPE( void do_slot_name, (message *mp) );
35 FORWARD _PROTOTYPE( void do_slot_name_s, (message *mp) );
36 FORWARD _PROTOTYPE( void do_acl, (message *mp) );
37 FORWARD _PROTOTYPE( void do_reserve, (message *mp) );
38 FORWARD _PROTOTYPE( void do_attr_r8, (message *mp) );
39 FORWARD _PROTOTYPE( void do_attr_r16, (message *mp) );
40 FORWARD _PROTOTYPE( void do_attr_r32, (message *mp) );
41 FORWARD _PROTOTYPE( void do_attr_w8, (message *mp) );
42 FORWARD _PROTOTYPE( void do_attr_w16, (message *mp) );
43 FORWARD _PROTOTYPE( void do_attr_w32, (message *mp) );
44 FORWARD _PROTOTYPE( void do_rescan_bus, (message *mp) );
45 FORWARD _PROTOTYPE( void reply, (message *mp, int result) );
46 FORWARD _PROTOTYPE( struct rs_pci *find_acl, (int endpoint) );
48 extern int debug;
50 int main(void)
52 int i, r;
53 message m;
55 pci_init();
57 for (i= 0; i<NR_DRIVERS; i++)
58 names[i].tasknr= ANY;
60 for(;;)
62 r= receive(ANY, &m);
63 if (r < 0)
65 printf("PCI: receive from ANY failed: %d\n", r);
66 break;
68 switch(m.m_type)
70 case BUSC_PCI_INIT: do_init(&m); break;
71 case BUSC_PCI_FIRST_DEV: do_first_dev(&m); break;
72 case BUSC_PCI_NEXT_DEV: do_next_dev(&m); break;
73 case BUSC_PCI_FIND_DEV: do_find_dev(&m); break;
74 case BUSC_PCI_IDS: do_ids(&m); break;
75 case BUSC_PCI_DEV_NAME: do_dev_name(&m); break;
76 case BUSC_PCI_SLOT_NAME: do_slot_name(&m); break;
77 case BUSC_PCI_RESERVE: do_reserve(&m); break;
78 case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
79 case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
80 case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
81 case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
82 case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
83 case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
84 case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
85 case BUSC_PCI_DEV_NAME_S: do_dev_name_s(&m); break;
86 case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&m); break;
87 case BUSC_PCI_ACL: do_acl(&m); break;
88 case PROC_EVENT: do_sig_handler(); break;
89 default:
90 printf("PCI: got message from %d, type %d\n",
91 m.m_source, m.m_type);
92 break;
96 return 0;
99 /*===========================================================================*
100 * do_sig_handler *
101 *===========================================================================*/
102 PRIVATE void do_sig_handler()
104 sigset_t sigset;
105 int sig;
107 /* Try to obtain signal set from PM. */
108 if (getsigset(&sigset) != 0) return;
110 /* Check for known signals. */
111 if (sigismember(&sigset, SIGTERM)) {
112 exit(0);
116 PRIVATE void do_init(mp)
117 message *mp;
119 int i, r, empty;
121 #if DEBUG
122 printf("PCI: pci_init: called by '%s'\n", mp->m3_ca1);
123 #endif
124 empty= -1;
125 for (i= 0; i<NR_DRIVERS; i++)
127 if (empty == -1 && names[i].tasknr == ANY)
128 empty= i;
129 if (strcmp(names[i].name, mp->m3_ca1) == 0)
130 break;
132 if (i >= NR_DRIVERS)
134 if (empty == -1)
135 panic("pci", "do_init: too many clients", NR_DRIVERS);
136 i= empty;
137 strcpy(names[i].name, mp->m3_ca1);
139 else if (names[i].tasknr == mp->m_source)
141 /* Ignore all init calls for a process after the first one */
143 #if 0
144 else
145 pci_release(names[i].name);
146 #endif
147 names[i].tasknr= mp->m_source;
149 mp->m_type= 0;
150 r= send(mp->m_source, mp);
151 if (r != 0)
152 printf("PCI: do_init: unable to send to %d: %d\n",
153 mp->m_source, r);
156 PRIVATE void do_first_dev(mp)
157 message *mp;
159 int i, r, devind;
160 u16_t vid, did;
161 struct rs_pci *aclp;
163 aclp= find_acl(mp->m_source);
165 if (!aclp && debug)
166 printf("PCI: do_first_dev: no acl for caller %d\n",
167 mp->m_source);
169 r= pci_first_dev_a(aclp, &devind, &vid, &did);
170 if (r == 1)
172 mp->m1_i1= devind;
173 mp->m1_i2= vid;
174 mp->m1_i3= did;
176 mp->m_type= r;
177 r= send(mp->m_source, mp);
178 if (r != 0)
180 printf("PCI: do_first_dev: unable to send to %d: %d\n",
181 mp->m_source, r);
185 PRIVATE void do_next_dev(mp)
186 message *mp;
188 int r, devind;
189 u16_t vid, did;
190 struct rs_pci *aclp;
192 devind= mp->m1_i1;
193 aclp= find_acl(mp->m_source);
195 r= pci_next_dev_a(aclp, &devind, &vid, &did);
196 if (r == 1)
198 mp->m1_i1= devind;
199 mp->m1_i2= vid;
200 mp->m1_i3= did;
202 mp->m_type= r;
203 r= send(mp->m_source, mp);
204 if (r != 0)
206 printf("PCI: do_next_dev: unable to send to %d: %d\n",
207 mp->m_source, r);
211 PRIVATE void do_find_dev(mp)
212 message *mp;
214 int r, devind;
215 u8_t bus, dev, func;
217 bus= mp->m1_i1;
218 dev= mp->m1_i2;
219 func= mp->m1_i3;
221 r= pci_find_dev(bus, dev, func, &devind);
222 if (r == 1)
223 mp->m1_i1= devind;
224 mp->m_type= r;
225 r= send(mp->m_source, mp);
226 if (r != 0)
228 printf("PCI: do_find_dev: unable to send to %d: %d\n",
229 mp->m_source, r);
233 PRIVATE void do_ids(mp)
234 message *mp;
236 int r, devind;
237 u16_t vid, did;
239 devind= mp->m1_i1;
241 pci_ids(devind, &vid, &did);
242 mp->m1_i1= vid;
243 mp->m1_i2= did;
244 mp->m_type= OK;
245 r= send(mp->m_source, mp);
246 if (r != 0)
248 printf("PCI: do_ids: unable to send to %d: %d\n",
249 mp->m_source, r);
253 PRIVATE void do_dev_name(mp)
254 message *mp;
256 int r, name_len, len;
257 u16_t vid, did;
258 char *name_ptr, *name;
260 vid= mp->m1_i1;
261 did= mp->m1_i2;
262 name_len= mp->m1_i3;
263 name_ptr= mp->m1_p1;
265 name= pci_dev_name(vid, did);
266 if (name == NULL)
268 /* No name */
269 r= ENOENT;
271 else
273 len= strlen(name)+1;
274 if (len > name_len)
275 len= name_len;
276 printf("PCI: pci`do_dev_name: calling do_vircopy\n");
277 r= sys_vircopy(SELF, D, (vir_bytes)name, mp->m_source, D,
278 (vir_bytes)name_ptr, len);
281 mp->m_type= r;
282 r= send(mp->m_source, mp);
283 if (r != 0)
285 printf("PCI: do_dev_name: unable to send to %d: %d\n",
286 mp->m_source, r);
290 PRIVATE void do_dev_name_s(mp)
291 message *mp;
293 int r, name_len, len;
294 u16_t vid, did;
295 cp_grant_id_t name_gid;
296 char *name;
298 vid= mp->m7_i1;
299 did= mp->m7_i2;
300 name_len= mp->m7_i3;
301 name_gid= mp->m7_i4;
303 name= pci_dev_name(vid, did);
304 if (name == NULL)
306 /* No name */
307 r= ENOENT;
309 else
311 len= strlen(name)+1;
312 if (len > name_len)
313 len= name_len;
314 r= sys_safecopyto(mp->m_source, name_gid, 0, (vir_bytes)name,
315 len, D);
318 mp->m_type= r;
319 r= send(mp->m_source, mp);
320 if (r != 0)
322 printf("PCI: do_dev_name: unable to send to %d: %d\n",
323 mp->m_source, r);
327 PRIVATE void do_slot_name(mp)
328 message *mp;
330 int r, devind, name_len, len;
331 char *name_ptr, *name;
333 devind= mp->m1_i1;
334 name_len= mp->m1_i2;
335 name_ptr= mp->m1_p1;
337 name= pci_slot_name(devind);
339 len= strlen(name)+1;
340 if (len > name_len)
341 len= name_len;
342 printf("PCI: pci`do_slot_name: calling do_vircopy\n");
343 r= sys_vircopy(SELF, D, (vir_bytes)name, mp->m_source, D,
344 (vir_bytes)name_ptr, len);
346 mp->m_type= r;
347 r= send(mp->m_source, mp);
348 if (r != 0)
350 printf("PCI: do_slot_name: unable to send to %d: %d\n",
351 mp->m_source, r);
355 PRIVATE void do_slot_name_s(mp)
356 message *mp;
358 int r, devind, name_len, len;
359 cp_grant_id_t gid;
360 char *name;
362 devind= mp->m1_i1;
363 name_len= mp->m1_i2;
364 gid= mp->m1_i3;
366 name= pci_slot_name(devind);
368 len= strlen(name)+1;
369 if (len > name_len)
370 len= name_len;
371 r= sys_safecopyto(mp->m_source, gid, 0, (vir_bytes)name, len, D);
373 mp->m_type= r;
374 r= send(mp->m_source, mp);
375 if (r != 0)
377 printf("PCI: do_slot_name: unable to send to %d: %d\n",
378 mp->m_source, r);
382 PRIVATE void do_acl(mp)
383 message *mp;
385 int i, r, gid;
387 if (mp->m_source != RS_PROC_NR)
389 printf("PCI: do_acl: not from RS\n");
390 reply(mp, EPERM);
391 return;
394 for (i= 0; i<NR_DRIVERS; i++)
396 if (!acl[i].inuse)
397 break;
399 if (i >= NR_DRIVERS)
401 printf("PCI: do_acl: table is full\n");
402 reply(mp, ENOMEM);
403 return;
406 gid= mp->m1_i1;
408 r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&acl[i].acl,
409 sizeof(acl[i].acl), D);
410 if (r != OK)
412 printf("PCI: do_acl: safecopyfrom failed\n");
413 reply(mp, r);
414 return;
416 acl[i].inuse= 1;
417 if(debug)
418 printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n",
419 acl[i].acl.rsp_endpoint, acl[i].acl.rsp_label,
422 reply(mp, OK);
425 PRIVATE void do_reserve(mp)
426 message *mp;
428 int i, r, devind;
430 /* Find the name of the caller */
431 for (i= 0; i<NR_DRIVERS; i++)
433 if (names[i].tasknr == mp->m_source)
434 break;
436 if (i >= NR_DRIVERS)
438 printf("pci`do_reserve: task %d did not call pci_init\n",
439 mp->m_source);
440 return;
443 devind= mp->m1_i1;
446 mp->m_type= pci_reserve3(devind, mp->m_source, names[i].name);
447 r= send(mp->m_source, mp);
448 if (r != 0)
450 printf("do_reserve: unable to send to %d: %d\n",
451 mp->m_source, r);
455 PRIVATE void do_attr_r8(mp)
456 message *mp;
458 int r, devind, port;
459 u8_t v;
461 devind= mp->m2_i1;
462 port= mp->m2_i2;
464 v= pci_attr_r8(devind, port);
465 mp->m2_l1= v;
466 mp->m_type= OK;
467 r= send(mp->m_source, mp);
468 if (r != 0)
470 printf("do_attr_r8: unable to send to %d: %d\n",
471 mp->m_source, r);
475 PRIVATE void do_attr_r16(mp)
476 message *mp;
478 int r, devind, port;
479 u32_t v;
481 devind= mp->m2_i1;
482 port= mp->m2_i2;
484 v= pci_attr_r16(devind, port);
485 mp->m2_l1= v;
486 mp->m_type= OK;
487 r= send(mp->m_source, mp);
488 if (r != 0)
490 printf("do_attr_r16: unable to send to %d: %d\n",
491 mp->m_source, r);
495 PRIVATE void do_attr_r32(mp)
496 message *mp;
498 int r, devind, port;
499 u32_t v;
501 devind= mp->m2_i1;
502 port= mp->m2_i2;
504 v= pci_attr_r32(devind, port);
505 mp->m2_l1= v;
506 mp->m_type= OK;
507 r= send(mp->m_source, mp);
508 if (r != 0)
510 printf("do_attr_r32: unable to send to %d: %d\n",
511 mp->m_source, r);
515 PRIVATE void do_attr_w8(mp)
516 message *mp;
518 int r, devind, port;
519 u8_t v;
521 devind= mp->m2_i1;
522 port= mp->m2_i2;
523 v= mp->m2_l1;
525 pci_attr_w8(devind, port, v);
526 mp->m_type= OK;
527 r= send(mp->m_source, mp);
528 if (r != 0)
530 printf("do_attr_w8: unable to send to %d: %d\n",
531 mp->m_source, r);
535 PRIVATE void do_attr_w16(mp)
536 message *mp;
538 int r, devind, port;
539 u16_t v;
541 devind= mp->m2_i1;
542 port= mp->m2_i2;
543 v= mp->m2_l1;
545 pci_attr_w16(devind, port, v);
546 mp->m_type= OK;
547 r= send(mp->m_source, mp);
548 if (r != 0)
550 printf("do_attr_w16: unable to send to %d: %d\n",
551 mp->m_source, r);
555 PRIVATE void do_attr_w32(mp)
556 message *mp;
558 int r, devind, port;
559 u32_t v;
561 devind= mp->m2_i1;
562 port= mp->m2_i2;
563 v= mp->m2_l1;
565 pci_attr_w32(devind, port, v);
566 mp->m_type= OK;
567 r= send(mp->m_source, mp);
568 if (r != 0)
570 printf("do_attr_w32: unable to send to %d: %d\n",
571 mp->m_source, r);
575 PRIVATE void do_rescan_bus(mp)
576 message *mp;
578 int r, busnr;
580 busnr= mp->m2_i1;
582 pci_rescan_bus(busnr);
583 mp->m_type= OK;
584 r= send(mp->m_source, mp);
585 if (r != 0)
587 printf("do_rescan_bus: unable to send to %d: %d\n",
588 mp->m_source, r);
593 PRIVATE void reply(mp, result)
594 message *mp;
595 int result;
597 int r;
598 message m;
600 m.m_type= result;
601 r= send(mp->m_source, &m);
602 if (r != 0)
603 printf("reply: unable to send to %d: %d\n", mp->m_source, r);
607 PRIVATE struct rs_pci *find_acl(endpoint)
608 int endpoint;
610 int i;
612 /* Find ACL entry for caller */
613 for (i= 0; i<NR_DRIVERS; i++)
615 if (!acl[i].inuse)
616 continue;
617 if (acl[i].acl.rsp_endpoint == endpoint)
618 return &acl[i].acl;
620 return NULL;