netbsd's original tr/extern.h as tr.h
[minix.git] / drivers / pci / main.c
blob64812764d67db10b617221ca536ffd1562f73758
1 /*
2 main.c
3 */
5 #include "pci.h"
7 PUBLIC struct pci_acl pci_acl[NR_DRIVERS];
9 FORWARD _PROTOTYPE( void do_init, (message *mp) );
10 FORWARD _PROTOTYPE( void do_first_dev, (message *mp) );
11 FORWARD _PROTOTYPE( void do_next_dev, (message *mp) );
12 FORWARD _PROTOTYPE( void do_find_dev, (message *mp) );
13 FORWARD _PROTOTYPE( void do_ids, (message *mp) );
14 FORWARD _PROTOTYPE( void do_dev_name, (message *mp) );
15 FORWARD _PROTOTYPE( void do_dev_name_s, (message *mp) );
16 FORWARD _PROTOTYPE( void do_slot_name_s, (message *mp) );
17 FORWARD _PROTOTYPE( void do_set_acl, (message *mp) );
18 FORWARD _PROTOTYPE( void do_del_acl, (message *mp) );
19 FORWARD _PROTOTYPE( void do_reserve, (message *mp) );
20 FORWARD _PROTOTYPE( void do_attr_r8, (message *mp) );
21 FORWARD _PROTOTYPE( void do_attr_r16, (message *mp) );
22 FORWARD _PROTOTYPE( void do_attr_r32, (message *mp) );
23 FORWARD _PROTOTYPE( void do_attr_w8, (message *mp) );
24 FORWARD _PROTOTYPE( void do_attr_w16, (message *mp) );
25 FORWARD _PROTOTYPE( void do_attr_w32, (message *mp) );
26 FORWARD _PROTOTYPE( void do_rescan_bus, (message *mp) );
27 FORWARD _PROTOTYPE( void reply, (message *mp, int result) );
28 FORWARD _PROTOTYPE( struct rs_pci *find_acl, (int endpoint) );
30 extern int debug;
32 /* SEF functions and variables. */
33 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
35 int main(void)
37 int i, 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_DEV_NAME: do_dev_name(&m); break;
68 case BUSC_PCI_RESERVE: do_reserve(&m); break;
69 case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
70 case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
71 case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
72 case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
73 case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
74 case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
75 case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
76 case BUSC_PCI_DEV_NAME_S: do_dev_name_s(&m); break;
77 case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&m); break;
78 case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
79 case BUSC_PCI_DEL_ACL: do_del_acl(&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 PRIVATE 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 PRIVATE 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 PRIVATE void do_first_dev(mp)
125 message *mp;
127 int i, r, devind;
128 u16_t vid, did;
129 struct rs_pci *aclp;
131 aclp= find_acl(mp->m_source);
133 if (!aclp && debug)
134 printf("PCI: do_first_dev: no acl for caller %d\n",
135 mp->m_source);
137 r= pci_first_dev_a(aclp, &devind, &vid, &did);
138 if (r == 1)
140 mp->m1_i1= devind;
141 mp->m1_i2= vid;
142 mp->m1_i3= did;
144 mp->m_type= r;
145 r= send(mp->m_source, mp);
146 if (r != 0)
148 printf("PCI: do_first_dev: unable to send to %d: %d\n",
149 mp->m_source, r);
153 PRIVATE void do_next_dev(mp)
154 message *mp;
156 int r, devind;
157 u16_t vid, did;
158 struct rs_pci *aclp;
160 devind= mp->m1_i1;
161 aclp= find_acl(mp->m_source);
163 r= pci_next_dev_a(aclp, &devind, &vid, &did);
164 if (r == 1)
166 mp->m1_i1= devind;
167 mp->m1_i2= vid;
168 mp->m1_i3= did;
170 mp->m_type= r;
171 r= send(mp->m_source, mp);
172 if (r != 0)
174 printf("PCI: do_next_dev: unable to send to %d: %d\n",
175 mp->m_source, r);
179 PRIVATE void do_find_dev(mp)
180 message *mp;
182 int r, devind;
183 u8_t bus, dev, func;
185 bus= mp->m1_i1;
186 dev= mp->m1_i2;
187 func= mp->m1_i3;
189 r= pci_find_dev(bus, dev, func, &devind);
190 if (r == 1)
191 mp->m1_i1= devind;
192 mp->m_type= r;
193 r= send(mp->m_source, mp);
194 if (r != 0)
196 printf("PCI: do_find_dev: unable to send to %d: %d\n",
197 mp->m_source, r);
201 PRIVATE void do_ids(mp)
202 message *mp;
204 int r, devind;
205 u16_t vid, did;
207 devind= mp->m1_i1;
209 r= pci_ids_s(devind, &vid, &did);
210 if (r != OK)
212 printf("pci:do_ids: failed for devind %d: %d\n",
213 devind, r);
216 mp->m1_i1= vid;
217 mp->m1_i2= did;
218 mp->m_type= r;
219 r= send(mp->m_source, mp);
220 if (r != 0)
222 printf("PCI: do_ids: unable to send to %d: %d\n",
223 mp->m_source, r);
227 PRIVATE void do_dev_name(mp)
228 message *mp;
230 int r, name_len, len;
231 u16_t vid, did;
232 char *name_ptr, *name;
234 vid= mp->m1_i1;
235 did= mp->m1_i2;
236 name_len= mp->m1_i3;
237 name_ptr= mp->m1_p1;
239 name= pci_dev_name(vid, did);
240 if (name == NULL)
242 /* No name */
243 r= ENOENT;
245 else
247 len= strlen(name)+1;
248 if (len > name_len)
249 len= name_len;
250 printf("PCI: pci`do_dev_name: calling do_vircopy\n");
251 r= sys_vircopy(SELF, D, (vir_bytes)name, mp->m_source, D,
252 (vir_bytes)name_ptr, len);
255 mp->m_type= r;
256 r= send(mp->m_source, mp);
257 if (r != 0)
259 printf("PCI: do_dev_name: unable to send to %d: %d\n",
260 mp->m_source, r);
264 PRIVATE void do_dev_name_s(mp)
265 message *mp;
267 int r, name_len, len;
268 u16_t vid, did;
269 cp_grant_id_t name_gid;
270 char *name;
272 vid= mp->m7_i1;
273 did= mp->m7_i2;
274 name_len= mp->m7_i3;
275 name_gid= mp->m7_i4;
277 name= pci_dev_name(vid, did);
278 if (name == NULL)
280 /* No name */
281 r= ENOENT;
283 else
285 len= strlen(name)+1;
286 if (len > name_len)
287 len= name_len;
288 r= sys_safecopyto(mp->m_source, name_gid, 0, (vir_bytes)name,
289 len, D);
292 mp->m_type= r;
293 r= send(mp->m_source, mp);
294 if (r != 0)
296 printf("PCI: do_dev_name: unable to send to %d: %d\n",
297 mp->m_source, r);
301 PRIVATE void do_slot_name_s(mp)
302 message *mp;
304 int r, devind, name_len, len;
305 cp_grant_id_t gid;
306 char *name;
308 devind= mp->m1_i1;
309 name_len= mp->m1_i2;
310 gid= mp->m1_i3;
312 r= pci_slot_name_s(devind, &name);
313 if (r != OK)
315 printf("pci:do_slot_name_s: failed for devind %d: %d\n",
316 devind, r);
319 if (r == OK)
321 len= strlen(name)+1;
322 if (len > name_len)
323 len= name_len;
324 r= sys_safecopyto(mp->m_source, gid, 0,
325 (vir_bytes)name, len, D);
328 mp->m_type= r;
329 r= send(mp->m_source, mp);
330 if (r != 0)
332 printf("PCI: do_slot_name: unable to send to %d: %d\n",
333 mp->m_source, r);
337 PRIVATE void do_set_acl(mp)
338 message *mp;
340 int i, r, gid;
342 if (mp->m_source != RS_PROC_NR)
344 printf("PCI: do_set_acl: not from RS\n");
345 reply(mp, EPERM);
346 return;
349 for (i= 0; i<NR_DRIVERS; i++)
351 if (!pci_acl[i].inuse)
352 break;
354 if (i >= NR_DRIVERS)
356 printf("PCI: do_set_acl: table is full\n");
357 reply(mp, ENOMEM);
358 return;
361 gid= mp->m1_i1;
363 r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&pci_acl[i].acl,
364 sizeof(pci_acl[i].acl), D);
365 if (r != OK)
367 printf("PCI: do_set_acl: safecopyfrom failed\n");
368 reply(mp, r);
369 return;
371 pci_acl[i].inuse= 1;
372 if(debug)
373 printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n",
374 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label,
377 reply(mp, OK);
380 PRIVATE void do_del_acl(mp)
381 message *mp;
383 int i, r, proc_nr;
385 if (mp->m_source != RS_PROC_NR)
387 printf("do_del_acl: not from RS\n");
388 reply(mp, EPERM);
389 return;
392 proc_nr= mp->m1_i1;
394 for (i= 0; i<NR_DRIVERS; i++)
396 if (!pci_acl[i].inuse)
397 continue;
398 if (pci_acl[i].acl.rsp_endpoint == proc_nr)
399 break;
402 if (i >= NR_DRIVERS)
404 printf("do_del_acl: nothing found for %d\n", proc_nr);
405 reply(mp, EINVAL);
406 return;
409 pci_acl[i].inuse= 0;
410 #if 0
411 printf("do_acl: deleting ACL for %d ('%s') at entry %d\n",
412 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label, i);
413 #endif
415 /* Also release all devices held by this process */
416 pci_release(proc_nr);
418 reply(mp, OK);
421 PRIVATE void do_reserve(mp)
422 message *mp;
424 int i, r, devind;
426 devind= mp->m1_i1;
428 mp->m_type= pci_reserve2(devind, mp->m_source);
429 r= send(mp->m_source, mp);
430 if (r != 0)
432 printf("do_reserve: unable to send to %d: %d\n",
433 mp->m_source, r);
437 PRIVATE void do_attr_r8(mp)
438 message *mp;
440 int r, devind, port;
441 u8_t v;
443 devind= mp->m2_i1;
444 port= mp->m2_i2;
446 r= pci_attr_r8_s(devind, port, &v);
447 if (r != OK)
449 printf(
450 "pci:do_attr_r8: pci_attr_r8_s(%d, %d, ...) failed: %d\n",
451 devind, port, r);
453 mp->m2_l1= v;
454 mp->m_type= r;
455 r= send(mp->m_source, mp);
456 if (r != 0)
458 printf("do_attr_r8: unable to send to %d: %d\n",
459 mp->m_source, r);
463 PRIVATE void do_attr_r16(mp)
464 message *mp;
466 int r, devind, port;
467 u32_t v;
469 devind= mp->m2_i1;
470 port= mp->m2_i2;
472 v= pci_attr_r16(devind, port);
473 mp->m2_l1= v;
474 mp->m_type= OK;
475 r= send(mp->m_source, mp);
476 if (r != 0)
478 printf("do_attr_r16: unable to send to %d: %d\n",
479 mp->m_source, r);
483 PRIVATE void do_attr_r32(mp)
484 message *mp;
486 int r, devind, port;
487 u32_t v;
489 devind= mp->m2_i1;
490 port= mp->m2_i2;
492 r= pci_attr_r32_s(devind, port, &v);
493 if (r != OK)
495 printf(
496 "pci:do_attr_r32: pci_attr_r32_s(%d, %d, ...) failed: %d\n",
497 devind, port, r);
499 mp->m2_l1= v;
500 mp->m_type= OK;
501 r= send(mp->m_source, mp);
502 if (r != 0)
504 printf("do_attr_r32: unable to send to %d: %d\n",
505 mp->m_source, r);
509 PRIVATE void do_attr_w8(mp)
510 message *mp;
512 int r, devind, port;
513 u8_t v;
515 devind= mp->m2_i1;
516 port= mp->m2_i2;
517 v= mp->m2_l1;
519 pci_attr_w8(devind, port, v);
520 mp->m_type= OK;
521 r= send(mp->m_source, mp);
522 if (r != 0)
524 printf("do_attr_w8: unable to send to %d: %d\n",
525 mp->m_source, r);
529 PRIVATE void do_attr_w16(mp)
530 message *mp;
532 int r, devind, port;
533 u16_t v;
535 devind= mp->m2_i1;
536 port= mp->m2_i2;
537 v= mp->m2_l1;
539 pci_attr_w16(devind, port, v);
540 mp->m_type= OK;
541 r= send(mp->m_source, mp);
542 if (r != 0)
544 printf("do_attr_w16: unable to send to %d: %d\n",
545 mp->m_source, r);
549 PRIVATE void do_attr_w32(mp)
550 message *mp;
552 int r, devind, port;
553 u32_t v;
555 devind= mp->m2_i1;
556 port= mp->m2_i2;
557 v= mp->m2_l1;
559 pci_attr_w32(devind, port, v);
560 mp->m_type= OK;
561 r= send(mp->m_source, mp);
562 if (r != 0)
564 printf("do_attr_w32: unable to send to %d: %d\n",
565 mp->m_source, r);
569 PRIVATE void do_rescan_bus(mp)
570 message *mp;
572 int r, busnr;
574 busnr= mp->m2_i1;
576 pci_rescan_bus(busnr);
577 mp->m_type= OK;
578 r= send(mp->m_source, mp);
579 if (r != 0)
581 printf("do_rescan_bus: unable to send to %d: %d\n",
582 mp->m_source, r);
587 PRIVATE void reply(mp, result)
588 message *mp;
589 int result;
591 int r;
592 message m;
594 m.m_type= result;
595 r= send(mp->m_source, &m);
596 if (r != 0)
597 printf("reply: unable to send to %d: %d\n", mp->m_source, r);
601 PRIVATE struct rs_pci *find_acl(endpoint)
602 int endpoint;
604 int i;
606 /* Find ACL entry for caller */
607 for (i= 0; i<NR_DRIVERS; i++)
609 if (!pci_acl[i].inuse)
610 continue;
611 if (pci_acl[i].acl.rsp_endpoint == endpoint)
612 return &pci_acl[i].acl;
614 return NULL;