dec21140A ethernet driver for virtualpc, contributed by nicolas tittley.
[minix.git] / drivers / pci / main.c
blob67c7c94fdb6a8d969ec9c06f561ff43c9ee64556
1 /*
2 main.c
3 */
5 #include "../drivers.h"
7 #include <ibm/pci.h>
8 #include <minix/rs.h>
9 #include <minix/endpoint.h>
11 #include "pci.h"
13 PUBLIC struct pci_acl pci_acl[NR_DRIVERS];
15 FORWARD _PROTOTYPE( void do_init, (message *mp) );
16 FORWARD _PROTOTYPE( void do_first_dev, (message *mp) );
17 FORWARD _PROTOTYPE( void do_next_dev, (message *mp) );
18 FORWARD _PROTOTYPE( void do_find_dev, (message *mp) );
19 FORWARD _PROTOTYPE( void do_ids, (message *mp) );
20 FORWARD _PROTOTYPE( void do_dev_name, (message *mp) );
21 FORWARD _PROTOTYPE( void do_dev_name_s, (message *mp) );
22 FORWARD _PROTOTYPE( void do_slot_name_s, (message *mp) );
23 FORWARD _PROTOTYPE( void do_set_acl, (message *mp) );
24 FORWARD _PROTOTYPE( void do_del_acl, (message *mp) );
25 FORWARD _PROTOTYPE( void do_reserve, (message *mp) );
26 FORWARD _PROTOTYPE( void do_attr_r8, (message *mp) );
27 FORWARD _PROTOTYPE( void do_attr_r16, (message *mp) );
28 FORWARD _PROTOTYPE( void do_attr_r32, (message *mp) );
29 FORWARD _PROTOTYPE( void do_attr_w8, (message *mp) );
30 FORWARD _PROTOTYPE( void do_attr_w16, (message *mp) );
31 FORWARD _PROTOTYPE( void do_attr_w32, (message *mp) );
32 FORWARD _PROTOTYPE( void do_rescan_bus, (message *mp) );
33 FORWARD _PROTOTYPE( void reply, (message *mp, int result) );
34 FORWARD _PROTOTYPE( struct rs_pci *find_acl, (int endpoint) );
36 extern int debug;
38 /* SEF functions and variables. */
39 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
41 int main(void)
43 int i, r;
44 message m;
46 /* SEF local startup. */
47 sef_local_startup();
49 for(;;)
51 r= sef_receive(ANY, &m);
52 if (r < 0)
54 printf("PCI: sef_receive from ANY failed: %d\n", r);
55 break;
58 if (is_notify(m.m_type)) {
59 switch (_ENDPOINT_P(m.m_source)) {
60 case PM_PROC_NR:
61 break;
62 default:
63 printf("PCI: got notify from %d\n",
64 m.m_source);
65 break;
68 /* done, get a new message */
69 continue;
72 switch(m.m_type)
74 case BUSC_PCI_INIT: do_init(&m); break;
75 case BUSC_PCI_FIRST_DEV: do_first_dev(&m); break;
76 case BUSC_PCI_NEXT_DEV: do_next_dev(&m); break;
77 case BUSC_PCI_FIND_DEV: do_find_dev(&m); break;
78 case BUSC_PCI_IDS: do_ids(&m); break;
79 case BUSC_PCI_DEV_NAME: do_dev_name(&m); break;
80 case BUSC_PCI_RESERVE: do_reserve(&m); break;
81 case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
82 case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
83 case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
84 case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
85 case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
86 case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
87 case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
88 case BUSC_PCI_DEV_NAME_S: do_dev_name_s(&m); break;
89 case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&m); break;
90 case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
91 case BUSC_PCI_DEL_ACL: do_del_acl(&m); break;
92 default:
93 printf("PCI: got message from %d, type %d\n",
94 m.m_source, m.m_type);
95 break;
99 return 0;
102 /*===========================================================================*
103 * sef_local_startup *
104 *===========================================================================*/
105 PRIVATE void sef_local_startup()
107 /* Register init callbacks. */
108 sef_setcb_init_fresh(sef_cb_init_fresh);
109 sef_setcb_init_lu(sef_cb_init_fresh);
110 sef_setcb_init_restart(sef_cb_init_fresh);
112 /* Register live update callbacks. */
113 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
114 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
116 /* Let SEF perform startup. */
117 sef_startup();
120 PRIVATE void do_init(mp)
121 message *mp;
123 int r;
125 #if DEBUG
126 printf("PCI: do_init: called by '%d'\n", mp->m_source);
127 #endif
129 mp->m_type= 0;
130 r= send(mp->m_source, mp);
131 if (r != 0)
132 printf("PCI: do_init: unable to send to %d: %d\n",
133 mp->m_source, r);
136 PRIVATE void do_first_dev(mp)
137 message *mp;
139 int i, r, devind;
140 u16_t vid, did;
141 struct rs_pci *aclp;
143 aclp= find_acl(mp->m_source);
145 if (!aclp && debug)
146 printf("PCI: do_first_dev: no acl for caller %d\n",
147 mp->m_source);
149 r= pci_first_dev_a(aclp, &devind, &vid, &did);
150 if (r == 1)
152 mp->m1_i1= devind;
153 mp->m1_i2= vid;
154 mp->m1_i3= did;
156 mp->m_type= r;
157 r= send(mp->m_source, mp);
158 if (r != 0)
160 printf("PCI: do_first_dev: unable to send to %d: %d\n",
161 mp->m_source, r);
165 PRIVATE void do_next_dev(mp)
166 message *mp;
168 int r, devind;
169 u16_t vid, did;
170 struct rs_pci *aclp;
172 devind= mp->m1_i1;
173 aclp= find_acl(mp->m_source);
175 r= pci_next_dev_a(aclp, &devind, &vid, &did);
176 if (r == 1)
178 mp->m1_i1= devind;
179 mp->m1_i2= vid;
180 mp->m1_i3= did;
182 mp->m_type= r;
183 r= send(mp->m_source, mp);
184 if (r != 0)
186 printf("PCI: do_next_dev: unable to send to %d: %d\n",
187 mp->m_source, r);
191 PRIVATE void do_find_dev(mp)
192 message *mp;
194 int r, devind;
195 u8_t bus, dev, func;
197 bus= mp->m1_i1;
198 dev= mp->m1_i2;
199 func= mp->m1_i3;
201 r= pci_find_dev(bus, dev, func, &devind);
202 if (r == 1)
203 mp->m1_i1= devind;
204 mp->m_type= r;
205 r= send(mp->m_source, mp);
206 if (r != 0)
208 printf("PCI: do_find_dev: unable to send to %d: %d\n",
209 mp->m_source, r);
213 PRIVATE void do_ids(mp)
214 message *mp;
216 int r, devind;
217 u16_t vid, did;
219 devind= mp->m1_i1;
221 r= pci_ids_s(devind, &vid, &did);
222 if (r != OK)
224 printf("pci:do_ids: failed for devind %d: %d\n",
225 devind, r);
228 mp->m1_i1= vid;
229 mp->m1_i2= did;
230 mp->m_type= r;
231 r= send(mp->m_source, mp);
232 if (r != 0)
234 printf("PCI: do_ids: unable to send to %d: %d\n",
235 mp->m_source, r);
239 PRIVATE void do_dev_name(mp)
240 message *mp;
242 int r, name_len, len;
243 u16_t vid, did;
244 char *name_ptr, *name;
246 vid= mp->m1_i1;
247 did= mp->m1_i2;
248 name_len= mp->m1_i3;
249 name_ptr= mp->m1_p1;
251 name= pci_dev_name(vid, did);
252 if (name == NULL)
254 /* No name */
255 r= ENOENT;
257 else
259 len= strlen(name)+1;
260 if (len > name_len)
261 len= name_len;
262 printf("PCI: pci`do_dev_name: calling do_vircopy\n");
263 r= sys_vircopy(SELF, D, (vir_bytes)name, mp->m_source, D,
264 (vir_bytes)name_ptr, len);
267 mp->m_type= r;
268 r= send(mp->m_source, mp);
269 if (r != 0)
271 printf("PCI: do_dev_name: unable to send to %d: %d\n",
272 mp->m_source, r);
276 PRIVATE void do_dev_name_s(mp)
277 message *mp;
279 int r, name_len, len;
280 u16_t vid, did;
281 cp_grant_id_t name_gid;
282 char *name;
284 vid= mp->m7_i1;
285 did= mp->m7_i2;
286 name_len= mp->m7_i3;
287 name_gid= mp->m7_i4;
289 name= pci_dev_name(vid, did);
290 if (name == NULL)
292 /* No name */
293 r= ENOENT;
295 else
297 len= strlen(name)+1;
298 if (len > name_len)
299 len= name_len;
300 r= sys_safecopyto(mp->m_source, name_gid, 0, (vir_bytes)name,
301 len, D);
304 mp->m_type= r;
305 r= send(mp->m_source, mp);
306 if (r != 0)
308 printf("PCI: do_dev_name: unable to send to %d: %d\n",
309 mp->m_source, r);
313 PRIVATE void do_slot_name_s(mp)
314 message *mp;
316 int r, devind, name_len, len;
317 cp_grant_id_t gid;
318 char *name;
320 devind= mp->m1_i1;
321 name_len= mp->m1_i2;
322 gid= mp->m1_i3;
324 r= pci_slot_name_s(devind, &name);
325 if (r != OK)
327 printf("pci:do_slot_name_s: failed for devind %d: %d\n",
328 devind, r);
331 if (r == OK)
333 len= strlen(name)+1;
334 if (len > name_len)
335 len= name_len;
336 r= sys_safecopyto(mp->m_source, gid, 0,
337 (vir_bytes)name, len, D);
340 mp->m_type= r;
341 r= send(mp->m_source, mp);
342 if (r != 0)
344 printf("PCI: do_slot_name: unable to send to %d: %d\n",
345 mp->m_source, r);
349 PRIVATE void do_set_acl(mp)
350 message *mp;
352 int i, r, gid;
354 if (mp->m_source != RS_PROC_NR)
356 printf("PCI: do_set_acl: not from RS\n");
357 reply(mp, EPERM);
358 return;
361 for (i= 0; i<NR_DRIVERS; i++)
363 if (!pci_acl[i].inuse)
364 break;
366 if (i >= NR_DRIVERS)
368 printf("PCI: do_set_acl: table is full\n");
369 reply(mp, ENOMEM);
370 return;
373 gid= mp->m1_i1;
375 r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&pci_acl[i].acl,
376 sizeof(pci_acl[i].acl), D);
377 if (r != OK)
379 printf("PCI: do_set_acl: safecopyfrom failed\n");
380 reply(mp, r);
381 return;
383 pci_acl[i].inuse= 1;
384 if(debug)
385 printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n",
386 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label,
389 reply(mp, OK);
392 PRIVATE void do_del_acl(mp)
393 message *mp;
395 int i, r, proc_nr;
397 if (mp->m_source != RS_PROC_NR)
399 printf("do_del_acl: not from RS\n");
400 reply(mp, EPERM);
401 return;
404 proc_nr= mp->m1_i1;
406 for (i= 0; i<NR_DRIVERS; i++)
408 if (!pci_acl[i].inuse)
409 continue;
410 if (pci_acl[i].acl.rsp_endpoint == proc_nr)
411 break;
414 if (i >= NR_DRIVERS)
416 printf("do_del_acl: nothing found for %d\n", proc_nr);
417 reply(mp, EINVAL);
418 return;
421 pci_acl[i].inuse= 0;
422 #if 0
423 printf("do_acl: deleting ACL for %d ('%s') at entry %d\n",
424 pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label, i);
425 #endif
427 /* Also release all devices held by this process */
428 pci_release(proc_nr);
430 reply(mp, OK);
433 PRIVATE void do_reserve(mp)
434 message *mp;
436 int i, r, devind;
438 devind= mp->m1_i1;
440 mp->m_type= pci_reserve2(devind, mp->m_source);
441 r= send(mp->m_source, mp);
442 if (r != 0)
444 printf("do_reserve: unable to send to %d: %d\n",
445 mp->m_source, r);
449 PRIVATE void do_attr_r8(mp)
450 message *mp;
452 int r, devind, port;
453 u8_t v;
455 devind= mp->m2_i1;
456 port= mp->m2_i2;
458 r= pci_attr_r8_s(devind, port, &v);
459 if (r != OK)
461 printf(
462 "pci:do_attr_r8: pci_attr_r8_s(%d, %d, ...) failed: %d\n",
463 devind, port, r);
465 mp->m2_l1= v;
466 mp->m_type= r;
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 r= pci_attr_r32_s(devind, port, &v);
505 if (r != OK)
507 printf(
508 "pci:do_attr_r32: pci_attr_r32_s(%d, %d, ...) failed: %d\n",
509 devind, port, r);
511 mp->m2_l1= v;
512 mp->m_type= OK;
513 r= send(mp->m_source, mp);
514 if (r != 0)
516 printf("do_attr_r32: unable to send to %d: %d\n",
517 mp->m_source, r);
521 PRIVATE void do_attr_w8(mp)
522 message *mp;
524 int r, devind, port;
525 u8_t v;
527 devind= mp->m2_i1;
528 port= mp->m2_i2;
529 v= mp->m2_l1;
531 pci_attr_w8(devind, port, v);
532 mp->m_type= OK;
533 r= send(mp->m_source, mp);
534 if (r != 0)
536 printf("do_attr_w8: unable to send to %d: %d\n",
537 mp->m_source, r);
541 PRIVATE void do_attr_w16(mp)
542 message *mp;
544 int r, devind, port;
545 u16_t v;
547 devind= mp->m2_i1;
548 port= mp->m2_i2;
549 v= mp->m2_l1;
551 pci_attr_w16(devind, port, v);
552 mp->m_type= OK;
553 r= send(mp->m_source, mp);
554 if (r != 0)
556 printf("do_attr_w16: unable to send to %d: %d\n",
557 mp->m_source, r);
561 PRIVATE void do_attr_w32(mp)
562 message *mp;
564 int r, devind, port;
565 u32_t v;
567 devind= mp->m2_i1;
568 port= mp->m2_i2;
569 v= mp->m2_l1;
571 pci_attr_w32(devind, port, v);
572 mp->m_type= OK;
573 r= send(mp->m_source, mp);
574 if (r != 0)
576 printf("do_attr_w32: unable to send to %d: %d\n",
577 mp->m_source, r);
581 PRIVATE void do_rescan_bus(mp)
582 message *mp;
584 int r, busnr;
586 busnr= mp->m2_i1;
588 pci_rescan_bus(busnr);
589 mp->m_type= OK;
590 r= send(mp->m_source, mp);
591 if (r != 0)
593 printf("do_rescan_bus: unable to send to %d: %d\n",
594 mp->m_source, r);
599 PRIVATE void reply(mp, result)
600 message *mp;
601 int result;
603 int r;
604 message m;
606 m.m_type= result;
607 r= send(mp->m_source, &m);
608 if (r != 0)
609 printf("reply: unable to send to %d: %d\n", mp->m_source, r);
613 PRIVATE struct rs_pci *find_acl(endpoint)
614 int endpoint;
616 int i;
618 /* Find ACL entry for caller */
619 for (i= 0; i<NR_DRIVERS; i++)
621 if (!pci_acl[i].inuse)
622 continue;
623 if (pci_acl[i].acl.rsp_endpoint == endpoint)
624 return &pci_acl[i].acl;
626 return NULL;