VM: full munmap
[minix.git] / drivers / pci / main.c
blob44fd49a599bf2cc2866c2ca823e898cdb61b12e4
1 /*
2 main.c
3 */
5 #include "pci.h"
7 struct pci_acl pci_acl[NR_DRIVERS];
9 static void do_init(message *mp);
10 static void do_first_dev(message *mp);
11 static void do_next_dev(message *mp);
12 static void do_find_dev(message *mp);
13 static void do_ids(message *mp);
14 static void do_dev_name_s(message *mp);
15 static void do_slot_name_s(message *mp);
16 static void do_set_acl(message *mp);
17 static void do_del_acl(message *mp);
18 static void do_reserve(message *mp);
19 static void do_attr_r8(message *mp);
20 static void do_attr_r16(message *mp);
21 static void do_attr_r32(message *mp);
22 static void do_attr_w8(message *mp);
23 static void do_attr_w16(message *mp);
24 static void do_attr_w32(message *mp);
25 static void do_get_bar(message *mp);
26 static void do_rescan_bus(message *mp);
27 static void reply(message *mp, int result);
28 static struct rs_pci *find_acl(int endpoint);
30 extern int debug;
32 /* SEF functions and variables. */
33 static void sef_local_startup(void);
35 int main(void)
37 int r;
38 message m;
39 int ipc_status;
41 /* SEF local startup. */
42 sef_local_startup();
44 for(;;)
46 r= driver_receive(ANY, &m, &ipc_status);
47 if (r < 0)
49 printf("PCI: driver_receive failed: %d\n", r);
50 break;
53 if (is_ipc_notify(ipc_status)) {
54 printf("PCI: got notify from %d\n", m.m_source);
56 /* done, get a new message */
57 continue;
60 switch(m.m_type)
62 case BUSC_PCI_INIT: do_init(&m); break;
63 case BUSC_PCI_FIRST_DEV: do_first_dev(&m); break;
64 case BUSC_PCI_NEXT_DEV: do_next_dev(&m); break;
65 case BUSC_PCI_FIND_DEV: do_find_dev(&m); break;
66 case BUSC_PCI_IDS: do_ids(&m); break;
67 case BUSC_PCI_RESERVE: do_reserve(&m); break;
68 case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
69 case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
70 case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
71 case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
72 case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
73 case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
74 case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
75 case BUSC_PCI_DEV_NAME_S: do_dev_name_s(&m); break;
76 case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&m); break;
77 case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
78 case BUSC_PCI_DEL_ACL: do_del_acl(&m); break;
79 case BUSC_PCI_GET_BAR: do_get_bar(&m); break;
80 default:
81 printf("PCI: got message from %d, type %d\n",
82 m.m_source, m.m_type);
83 break;
87 return 0;
90 /*===========================================================================*
91 * sef_local_startup *
92 *===========================================================================*/
93 static void sef_local_startup()
95 /* Register init callbacks. */
96 sef_setcb_init_fresh(sef_cb_init_fresh);
97 sef_setcb_init_lu(sef_cb_init_fresh);
98 sef_setcb_init_restart(sef_cb_init_fresh);
100 /* Register live update callbacks. */
101 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
102 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
104 /* Let SEF perform startup. */
105 sef_startup();
108 static void do_init(mp)
109 message *mp;
111 int r;
113 #if DEBUG
114 printf("PCI: do_init: called by '%d'\n", mp->m_source);
115 #endif
117 mp->m_type= 0;
118 r= send(mp->m_source, mp);
119 if (r != 0)
120 printf("PCI: do_init: unable to send to %d: %d\n",
121 mp->m_source, r);
124 static void do_first_dev(message *mp)
126 int r, devind;
127 u16_t vid, did;
128 struct rs_pci *aclp;
130 aclp= find_acl(mp->m_source);
132 if (!aclp && debug)
133 printf("PCI: do_first_dev: no acl for caller %d\n",
134 mp->m_source);
136 r= pci_first_dev_a(aclp, &devind, &vid, &did);
137 if (r == 1)
139 mp->m1_i1= devind;
140 mp->m1_i2= vid;
141 mp->m1_i3= did;
143 mp->m_type= r;
144 r= send(mp->m_source, mp);
145 if (r != 0)
147 printf("PCI: do_first_dev: unable to send to %d: %d\n",
148 mp->m_source, r);
152 static void do_next_dev(message *mp)
154 int r, devind;
155 u16_t vid, did;
156 struct rs_pci *aclp;
158 devind= mp->m1_i1;
159 aclp= find_acl(mp->m_source);
161 r= pci_next_dev_a(aclp, &devind, &vid, &did);
162 if (r == 1)
164 mp->m1_i1= devind;
165 mp->m1_i2= vid;
166 mp->m1_i3= did;
168 mp->m_type= r;
169 r= send(mp->m_source, mp);
170 if (r != 0)
172 printf("PCI: do_next_dev: unable to send to %d: %d\n",
173 mp->m_source, r);
177 static void do_find_dev(mp)
178 message *mp;
180 int r, devind;
181 u8_t bus, dev, func;
183 bus= mp->m1_i1;
184 dev= mp->m1_i2;
185 func= mp->m1_i3;
187 r= pci_find_dev(bus, dev, func, &devind);
188 if (r == 1)
189 mp->m1_i1= devind;
190 mp->m_type= r;
191 r= send(mp->m_source, mp);
192 if (r != 0)
194 printf("PCI: do_find_dev: unable to send to %d: %d\n",
195 mp->m_source, r);
199 static void do_ids(mp)
200 message *mp;
202 int r, devind;
203 u16_t vid, did;
205 devind= mp->m1_i1;
207 r= pci_ids_s(devind, &vid, &did);
208 if (r != OK)
210 printf("pci:do_ids: failed for devind %d: %d\n",
211 devind, r);
214 mp->m1_i1= vid;
215 mp->m1_i2= did;
216 mp->m_type= r;
217 r= send(mp->m_source, mp);
218 if (r != 0)
220 printf("PCI: do_ids: unable to send to %d: %d\n",
221 mp->m_source, r);
225 static void do_dev_name_s(mp)
226 message *mp;
228 int r, name_len, len;
229 u16_t vid, did;
230 cp_grant_id_t name_gid;
231 char *name;
233 vid= mp->m7_i1;
234 did= mp->m7_i2;
235 name_len= mp->m7_i3;
236 name_gid= mp->m7_i4;
238 name= pci_dev_name(vid, did);
239 if (name == NULL)
241 /* No name */
242 r= ENOENT;
244 else
246 len= strlen(name)+1;
247 if (len > name_len)
248 len= name_len;
249 r= sys_safecopyto(mp->m_source, name_gid, 0, (vir_bytes)name,
250 len);
253 mp->m_type= r;
254 r= send(mp->m_source, mp);
255 if (r != 0)
257 printf("PCI: do_dev_name: unable to send to %d: %d\n",
258 mp->m_source, r);
262 static void do_slot_name_s(mp)
263 message *mp;
265 int r, devind, name_len, len;
266 cp_grant_id_t gid;
267 char *name;
269 devind= mp->m1_i1;
270 name_len= mp->m1_i2;
271 gid= mp->m1_i3;
273 r= pci_slot_name_s(devind, &name);
274 if (r != OK)
276 printf("pci:do_slot_name_s: failed for devind %d: %d\n",
277 devind, r);
280 if (r == OK)
282 len= strlen(name)+1;
283 if (len > name_len)
284 len= name_len;
285 r= sys_safecopyto(mp->m_source, gid, 0,
286 (vir_bytes)name, len);
289 mp->m_type= r;
290 r= send(mp->m_source, mp);
291 if (r != 0)
293 printf("PCI: do_slot_name: unable to send to %d: %d\n",
294 mp->m_source, r);
298 static void do_set_acl(mp)
299 message *mp;
301 int i, r, gid;
303 if (mp->m_source != RS_PROC_NR)
305 printf("PCI: do_set_acl: not from RS\n");
306 reply(mp, EPERM);
307 return;
310 for (i= 0; i<NR_DRIVERS; i++)
312 if (!pci_acl[i].inuse)
313 break;
315 if (i >= NR_DRIVERS)
317 printf("PCI: do_set_acl: table is full\n");
318 reply(mp, ENOMEM);
319 return;
322 gid= mp->m1_i1;
324 r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&pci_acl[i].acl,
325 sizeof(pci_acl[i].acl));
326 if (r != OK)
328 printf("PCI: do_set_acl: safecopyfrom failed\n");
329 reply(mp, r);
330 return;
332 pci_acl[i].inuse= 1;
333 if(debug)
334 printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n",
335 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label,
338 reply(mp, OK);
341 static void do_del_acl(message *mp)
343 int i, proc_nr;
345 if (mp->m_source != RS_PROC_NR)
347 printf("do_del_acl: not from RS\n");
348 reply(mp, EPERM);
349 return;
352 proc_nr= mp->m1_i1;
354 for (i= 0; i<NR_DRIVERS; i++)
356 if (!pci_acl[i].inuse)
357 continue;
358 if (pci_acl[i].acl.rsp_endpoint == proc_nr)
359 break;
362 if (i >= NR_DRIVERS)
364 printf("do_del_acl: nothing found for %d\n", proc_nr);
365 reply(mp, EINVAL);
366 return;
369 pci_acl[i].inuse= 0;
370 #if 0
371 printf("do_acl: deleting ACL for %d ('%s') at entry %d\n",
372 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label, i);
373 #endif
375 /* Also release all devices held by this process */
376 pci_release(proc_nr);
378 reply(mp, OK);
381 static void do_reserve(message *mp)
383 struct rs_pci *aclp;
384 int r, devind;
386 devind= mp->m1_i1;
388 aclp= find_acl(mp->m_source);
390 mp->m_type= pci_reserve_a(devind, mp->m_source, aclp);
391 r= send(mp->m_source, mp);
392 if (r != 0)
394 printf("do_reserve: unable to send to %d: %d\n",
395 mp->m_source, r);
399 static void do_attr_r8(mp)
400 message *mp;
402 int r, devind, port;
403 u8_t v;
405 devind= mp->m2_i1;
406 port= mp->m2_i2;
408 r= pci_attr_r8_s(devind, port, &v);
409 if (r != OK)
411 printf(
412 "pci:do_attr_r8: pci_attr_r8_s(%d, %d, ...) failed: %d\n",
413 devind, port, r);
415 mp->m2_l1= v;
416 mp->m_type= r;
417 r= send(mp->m_source, mp);
418 if (r != 0)
420 printf("do_attr_r8: unable to send to %d: %d\n",
421 mp->m_source, r);
425 static void do_attr_r16(mp)
426 message *mp;
428 int r, devind, port;
429 u32_t v;
431 devind= mp->m2_i1;
432 port= mp->m2_i2;
434 v= pci_attr_r16(devind, port);
435 mp->m2_l1= v;
436 mp->m_type= OK;
437 r= send(mp->m_source, mp);
438 if (r != 0)
440 printf("do_attr_r16: unable to send to %d: %d\n",
441 mp->m_source, r);
445 static void do_attr_r32(mp)
446 message *mp;
448 int r, devind, port;
449 u32_t v;
451 devind= mp->m2_i1;
452 port= mp->m2_i2;
454 r= pci_attr_r32_s(devind, port, &v);
455 if (r != OK)
457 printf(
458 "pci:do_attr_r32: pci_attr_r32_s(%d, %d, ...) failed: %d\n",
459 devind, port, r);
461 mp->m2_l1= v;
462 mp->m_type= OK;
463 r= send(mp->m_source, mp);
464 if (r != 0)
466 printf("do_attr_r32: unable to send to %d: %d\n",
467 mp->m_source, r);
471 static void do_attr_w8(mp)
472 message *mp;
474 int r, devind, port;
475 u8_t v;
477 devind= mp->m2_i1;
478 port= mp->m2_i2;
479 v= mp->m2_l1;
481 pci_attr_w8(devind, port, v);
482 mp->m_type= OK;
483 r= send(mp->m_source, mp);
484 if (r != 0)
486 printf("do_attr_w8: unable to send to %d: %d\n",
487 mp->m_source, r);
491 static void do_attr_w16(mp)
492 message *mp;
494 int r, devind, port;
495 u16_t v;
497 devind= mp->m2_i1;
498 port= mp->m2_i2;
499 v= mp->m2_l1;
501 pci_attr_w16(devind, port, v);
502 mp->m_type= OK;
503 r= send(mp->m_source, mp);
504 if (r != 0)
506 printf("do_attr_w16: unable to send to %d: %d\n",
507 mp->m_source, r);
511 static void do_attr_w32(mp)
512 message *mp;
514 int r, devind, port;
515 u32_t v;
517 devind= mp->m2_i1;
518 port= mp->m2_i2;
519 v= mp->m2_l1;
521 pci_attr_w32(devind, port, v);
522 mp->m_type= OK;
523 r= send(mp->m_source, mp);
524 if (r != 0)
526 printf("do_attr_w32: unable to send to %d: %d\n",
527 mp->m_source, r);
531 static void do_get_bar(mp)
532 message *mp;
534 int r, devind, port, ioflag;
535 u32_t base, size;
537 devind= mp->BUSC_PGB_DEVIND;
538 port= mp->BUSC_PGB_PORT;
540 mp->m_type= pci_get_bar_s(devind, port, &base, &size, &ioflag);
542 if (mp->m_type == OK)
544 mp->BUSC_PGB_BASE= base;
545 mp->BUSC_PGB_SIZE= size;
546 mp->BUSC_PGB_IOFLAG= ioflag;
549 r= send(mp->m_source, mp);
550 if (r != 0)
552 printf("do_get_bar: unable to send to %d: %d\n",
553 mp->m_source, r);
557 static void do_rescan_bus(mp)
558 message *mp;
560 int r, busnr;
562 busnr= mp->m2_i1;
564 pci_rescan_bus(busnr);
565 mp->m_type= OK;
566 r= send(mp->m_source, mp);
567 if (r != 0)
569 printf("do_rescan_bus: unable to send to %d: %d\n",
570 mp->m_source, r);
575 static void reply(mp, result)
576 message *mp;
577 int result;
579 int r;
580 message m;
582 m.m_type= result;
583 r= send(mp->m_source, &m);
584 if (r != 0)
585 printf("reply: unable to send to %d: %d\n", mp->m_source, r);
589 static struct rs_pci *find_acl(endpoint)
590 int endpoint;
592 int i;
594 /* Find ACL entry for caller */
595 for (i= 0; i<NR_DRIVERS; i++)
597 if (!pci_acl[i].inuse)
598 continue;
599 if (pci_acl[i].acl.rsp_endpoint == endpoint)
600 return &pci_acl[i].acl;
602 return NULL;