3.1.7 branch.
[minix.git] / drivers / pci / main.c
blob8ddd0cc4da45d17ada1f60d2243f28d14c108ded
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 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(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 PRIVATE 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 PRIVATE 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 PRIVATE 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 PRIVATE void do_dev_name(mp)
226 message *mp;
228 int r, name_len, len;
229 u16_t vid, did;
230 char *name_ptr, *name;
232 vid= mp->m1_i1;
233 did= mp->m1_i2;
234 name_len= mp->m1_i3;
235 name_ptr= mp->m1_p1;
237 name= pci_dev_name(vid, did);
238 if (name == NULL)
240 /* No name */
241 r= ENOENT;
243 else
245 len= strlen(name)+1;
246 if (len > name_len)
247 len= name_len;
248 printf("PCI: pci`do_dev_name: calling do_vircopy\n");
249 r= sys_vircopy(SELF, D, (vir_bytes)name, mp->m_source, D,
250 (vir_bytes)name_ptr, 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 PRIVATE void do_dev_name_s(mp)
263 message *mp;
265 int r, name_len, len;
266 u16_t vid, did;
267 cp_grant_id_t name_gid;
268 char *name;
270 vid= mp->m7_i1;
271 did= mp->m7_i2;
272 name_len= mp->m7_i3;
273 name_gid= mp->m7_i4;
275 name= pci_dev_name(vid, did);
276 if (name == NULL)
278 /* No name */
279 r= ENOENT;
281 else
283 len= strlen(name)+1;
284 if (len > name_len)
285 len= name_len;
286 r= sys_safecopyto(mp->m_source, name_gid, 0, (vir_bytes)name,
287 len, D);
290 mp->m_type= r;
291 r= send(mp->m_source, mp);
292 if (r != 0)
294 printf("PCI: do_dev_name: unable to send to %d: %d\n",
295 mp->m_source, r);
299 PRIVATE void do_slot_name_s(mp)
300 message *mp;
302 int r, devind, name_len, len;
303 cp_grant_id_t gid;
304 char *name;
306 devind= mp->m1_i1;
307 name_len= mp->m1_i2;
308 gid= mp->m1_i3;
310 r= pci_slot_name_s(devind, &name);
311 if (r != OK)
313 printf("pci:do_slot_name_s: failed for devind %d: %d\n",
314 devind, r);
317 if (r == OK)
319 len= strlen(name)+1;
320 if (len > name_len)
321 len= name_len;
322 r= sys_safecopyto(mp->m_source, gid, 0,
323 (vir_bytes)name, len, D);
326 mp->m_type= r;
327 r= send(mp->m_source, mp);
328 if (r != 0)
330 printf("PCI: do_slot_name: unable to send to %d: %d\n",
331 mp->m_source, r);
335 PRIVATE void do_set_acl(mp)
336 message *mp;
338 int i, r, gid;
340 if (mp->m_source != RS_PROC_NR)
342 printf("PCI: do_set_acl: not from RS\n");
343 reply(mp, EPERM);
344 return;
347 for (i= 0; i<NR_DRIVERS; i++)
349 if (!pci_acl[i].inuse)
350 break;
352 if (i >= NR_DRIVERS)
354 printf("PCI: do_set_acl: table is full\n");
355 reply(mp, ENOMEM);
356 return;
359 gid= mp->m1_i1;
361 r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&pci_acl[i].acl,
362 sizeof(pci_acl[i].acl), D);
363 if (r != OK)
365 printf("PCI: do_set_acl: safecopyfrom failed\n");
366 reply(mp, r);
367 return;
369 pci_acl[i].inuse= 1;
370 if(debug)
371 printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n",
372 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label,
375 reply(mp, OK);
378 PRIVATE void do_del_acl(message *mp)
380 int i, proc_nr;
382 if (mp->m_source != RS_PROC_NR)
384 printf("do_del_acl: not from RS\n");
385 reply(mp, EPERM);
386 return;
389 proc_nr= mp->m1_i1;
391 for (i= 0; i<NR_DRIVERS; i++)
393 if (!pci_acl[i].inuse)
394 continue;
395 if (pci_acl[i].acl.rsp_endpoint == proc_nr)
396 break;
399 if (i >= NR_DRIVERS)
401 printf("do_del_acl: nothing found for %d\n", proc_nr);
402 reply(mp, EINVAL);
403 return;
406 pci_acl[i].inuse= 0;
407 #if 0
408 printf("do_acl: deleting ACL for %d ('%s') at entry %d\n",
409 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label, i);
410 #endif
412 /* Also release all devices held by this process */
413 pci_release(proc_nr);
415 reply(mp, OK);
418 PRIVATE void do_reserve(message *mp)
420 int r, devind;
422 devind= mp->m1_i1;
424 mp->m_type= pci_reserve2(devind, mp->m_source);
425 r= send(mp->m_source, mp);
426 if (r != 0)
428 printf("do_reserve: unable to send to %d: %d\n",
429 mp->m_source, r);
433 PRIVATE void do_attr_r8(mp)
434 message *mp;
436 int r, devind, port;
437 u8_t v;
439 devind= mp->m2_i1;
440 port= mp->m2_i2;
442 r= pci_attr_r8_s(devind, port, &v);
443 if (r != OK)
445 printf(
446 "pci:do_attr_r8: pci_attr_r8_s(%d, %d, ...) failed: %d\n",
447 devind, port, r);
449 mp->m2_l1= v;
450 mp->m_type= r;
451 r= send(mp->m_source, mp);
452 if (r != 0)
454 printf("do_attr_r8: unable to send to %d: %d\n",
455 mp->m_source, r);
459 PRIVATE void do_attr_r16(mp)
460 message *mp;
462 int r, devind, port;
463 u32_t v;
465 devind= mp->m2_i1;
466 port= mp->m2_i2;
468 v= pci_attr_r16(devind, port);
469 mp->m2_l1= v;
470 mp->m_type= OK;
471 r= send(mp->m_source, mp);
472 if (r != 0)
474 printf("do_attr_r16: unable to send to %d: %d\n",
475 mp->m_source, r);
479 PRIVATE void do_attr_r32(mp)
480 message *mp;
482 int r, devind, port;
483 u32_t v;
485 devind= mp->m2_i1;
486 port= mp->m2_i2;
488 r= pci_attr_r32_s(devind, port, &v);
489 if (r != OK)
491 printf(
492 "pci:do_attr_r32: pci_attr_r32_s(%d, %d, ...) failed: %d\n",
493 devind, port, r);
495 mp->m2_l1= v;
496 mp->m_type= OK;
497 r= send(mp->m_source, mp);
498 if (r != 0)
500 printf("do_attr_r32: unable to send to %d: %d\n",
501 mp->m_source, r);
505 PRIVATE void do_attr_w8(mp)
506 message *mp;
508 int r, devind, port;
509 u8_t v;
511 devind= mp->m2_i1;
512 port= mp->m2_i2;
513 v= mp->m2_l1;
515 pci_attr_w8(devind, port, v);
516 mp->m_type= OK;
517 r= send(mp->m_source, mp);
518 if (r != 0)
520 printf("do_attr_w8: unable to send to %d: %d\n",
521 mp->m_source, r);
525 PRIVATE void do_attr_w16(mp)
526 message *mp;
528 int r, devind, port;
529 u16_t v;
531 devind= mp->m2_i1;
532 port= mp->m2_i2;
533 v= mp->m2_l1;
535 pci_attr_w16(devind, port, v);
536 mp->m_type= OK;
537 r= send(mp->m_source, mp);
538 if (r != 0)
540 printf("do_attr_w16: unable to send to %d: %d\n",
541 mp->m_source, r);
545 PRIVATE void do_attr_w32(mp)
546 message *mp;
548 int r, devind, port;
549 u32_t v;
551 devind= mp->m2_i1;
552 port= mp->m2_i2;
553 v= mp->m2_l1;
555 pci_attr_w32(devind, port, v);
556 mp->m_type= OK;
557 r= send(mp->m_source, mp);
558 if (r != 0)
560 printf("do_attr_w32: unable to send to %d: %d\n",
561 mp->m_source, r);
565 PRIVATE void do_rescan_bus(mp)
566 message *mp;
568 int r, busnr;
570 busnr= mp->m2_i1;
572 pci_rescan_bus(busnr);
573 mp->m_type= OK;
574 r= send(mp->m_source, mp);
575 if (r != 0)
577 printf("do_rescan_bus: unable to send to %d: %d\n",
578 mp->m_source, r);
583 PRIVATE void reply(mp, result)
584 message *mp;
585 int result;
587 int r;
588 message m;
590 m.m_type= result;
591 r= send(mp->m_source, &m);
592 if (r != 0)
593 printf("reply: unable to send to %d: %d\n", mp->m_source, r);
597 PRIVATE struct rs_pci *find_acl(endpoint)
598 int endpoint;
600 int i;
602 /* Find ACL entry for caller */
603 for (i= 0; i<NR_DRIVERS; i++)
605 if (!pci_acl[i].inuse)
606 continue;
607 if (pci_acl[i].acl.rsp_endpoint == endpoint)
608 return &pci_acl[i].acl;
610 return NULL;