1 /* 2 main.c 3 */ 4 5 #include "pci.h" 6 7 struct pci_acl pci_acl[NR_DRIVERS]; 8 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); 29 30 extern int debug; 31 32 /* SEF functions and variables. */ 33 static void sef_local_startup(void); 34 35 int main(void) 36 { 37 int r; 38 message m; 39 int ipc_status; 40 41 /* SEF local startup. */ 42 sef_local_startup(); 43 44 for(;;) 45 { 46 r= driver_receive(ANY, &m, &ipc_status); 47 if (r < 0) 48 { 49 printf("PCI: driver_receive failed: %d\n", r); 50 break; 51 } 52 53 if (is_ipc_notify(ipc_status)) { 54 printf("PCI: got notify from %d\n", m.m_source); 55 56 /* done, get a new message */ 57 continue; 58 } 59 60 switch(m.m_type) 61 { 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; 84 } 85 } 86 87 return 0; 88 } 89 90 /*===========================================================================* 91 * sef_local_startup * 92 *===========================================================================*/ 93 static void sef_local_startup() 94 { 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); 99 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); 103 104 /* Let SEF perform startup. */ 105 sef_startup(); 106 } 107 108 static void do_init(mp) 109 message *mp; 110 { 111 int r; 112 113 #if DEBUG 114 printf("PCI: do_init: called by '%d'\n", mp->m_source); 115 #endif 116 117 mp->m_type= 0; 118 r= ipc_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); 122 } 123 124 static void do_first_dev(message *mp) 125 { 126 int r, devind; 127 u16_t vid, did; 128 struct rs_pci *aclp; 129 130 aclp= find_acl(mp->m_source); 131 132 if (!aclp && debug) 133 printf("PCI: do_first_dev: no acl for caller %d\n", 134 mp->m_source); 135 136 r= pci_first_dev_a(aclp, &devind, &vid, &did); 137 if (r == 1) 138 { 139 mp->m1_i1= devind; 140 mp->m1_i2= vid; 141 mp->m1_i3= did; 142 } 143 mp->m_type= r; 144 r= ipc_send(mp->m_source, mp); 145 if (r != 0) 146 { 147 printf("PCI: do_first_dev: unable to send to %d: %d\n", 148 mp->m_source, r); 149 } 150 } 151 152 static void do_next_dev(message *mp) 153 { 154 int r, devind; 155 u16_t vid, did; 156 struct rs_pci *aclp; 157 158 devind= mp->m1_i1; 159 aclp= find_acl(mp->m_source); 160 161 r= pci_next_dev_a(aclp, &devind, &vid, &did); 162 if (r == 1) 163 { 164 mp->m1_i1= devind; 165 mp->m1_i2= vid; 166 mp->m1_i3= did; 167 } 168 mp->m_type= r; 169 r= ipc_send(mp->m_source, mp); 170 if (r != 0) 171 { 172 printf("PCI: do_next_dev: unable to send to %d: %d\n", 173 mp->m_source, r); 174 } 175 } 176 177 static void do_find_dev(mp) 178 message *mp; 179 { 180 int r, devind; 181 u8_t bus, dev, func; 182 183 bus= mp->m1_i1; 184 dev= mp->m1_i2; 185 func= mp->m1_i3; 186 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= ipc_send(mp->m_source, mp); 192 if (r != 0) 193 { 194 printf("PCI: do_find_dev: unable to send to %d: %d\n", 195 mp->m_source, r); 196 } 197 } 198 199 static void do_ids(mp) 200 message *mp; 201 { 202 int r, devind; 203 u16_t vid, did; 204 205 devind= mp->m1_i1; 206 207 r= pci_ids_s(devind, &vid, &did); 208 if (r != OK) 209 { 210 printf("pci:do_ids: failed for devind %d: %d\n", 211 devind, r); 212 } 213 214 mp->m1_i1= vid; 215 mp->m1_i2= did; 216 mp->m_type= r; 217 r= ipc_send(mp->m_source, mp); 218 if (r != 0) 219 { 220 printf("PCI: do_ids: unable to send to %d: %d\n", 221 mp->m_source, r); 222 } 223 } 224 225 static void do_dev_name_s(mp) 226 message *mp; 227 { 228 int r, name_len, len; 229 u16_t vid, did; 230 cp_grant_id_t name_gid; 231 char *name; 232 233 vid= mp->m7_i1; 234 did= mp->m7_i2; 235 name_len= mp->m7_i3; 236 name_gid= mp->m7_i4; 237 238 name= pci_dev_name(vid, did); 239 if (name == NULL) 240 { 241 /* No name */ 242 r= ENOENT; 243 } 244 else 245 { 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); 251 } 252 253 mp->m_type= r; 254 r= ipc_send(mp->m_source, mp); 255 if (r != 0) 256 { 257 printf("PCI: do_dev_name: unable to send to %d: %d\n", 258 mp->m_source, r); 259 } 260 } 261 262 static void do_slot_name_s(mp) 263 message *mp; 264 { 265 int r, devind, name_len, len; 266 cp_grant_id_t gid; 267 char *name; 268 269 devind= mp->m1_i1; 270 name_len= mp->m1_i2; 271 gid= mp->m1_i3; 272 273 r= pci_slot_name_s(devind, &name); 274 if (r != OK) 275 { 276 printf("pci:do_slot_name_s: failed for devind %d: %d\n", 277 devind, r); 278 } 279 280 if (r == OK) 281 { 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); 287 } 288 289 mp->m_type= r; 290 r= ipc_send(mp->m_source, mp); 291 if (r != 0) 292 { 293 printf("PCI: do_slot_name: unable to send to %d: %d\n", 294 mp->m_source, r); 295 } 296 } 297 298 static void do_set_acl(mp) 299 message *mp; 300 { 301 int i, r, gid; 302 303 if (mp->m_source != RS_PROC_NR) 304 { 305 printf("PCI: do_set_acl: not from RS\n"); 306 reply(mp, EPERM); 307 return; 308 } 309 310 for (i= 0; i<NR_DRIVERS; i++) 311 { 312 if (!pci_acl[i].inuse) 313 break; 314 } 315 if (i >= NR_DRIVERS) 316 { 317 printf("PCI: do_set_acl: table is full\n"); 318 reply(mp, ENOMEM); 319 return; 320 } 321 322 gid= mp->m1_i1; 323 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) 327 { 328 printf("PCI: do_set_acl: safecopyfrom failed\n"); 329 reply(mp, r); 330 return; 331 } 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, 336 i); 337 338 reply(mp, OK); 339 } 340 341 static void do_del_acl(message *mp) 342 { 343 int i, proc_nr; 344 345 if (mp->m_source != RS_PROC_NR) 346 { 347 printf("do_del_acl: not from RS\n"); 348 reply(mp, EPERM); 349 return; 350 } 351 352 proc_nr= mp->m1_i1; 353 354 for (i= 0; i<NR_DRIVERS; i++) 355 { 356 if (!pci_acl[i].inuse) 357 continue; 358 if (pci_acl[i].acl.rsp_endpoint == proc_nr) 359 break; 360 } 361 362 if (i >= NR_DRIVERS) 363 { 364 printf("do_del_acl: nothing found for %d\n", proc_nr); 365 reply(mp, EINVAL); 366 return; 367 } 368 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 374 375 /* Also release all devices held by this process */ 376 pci_release(proc_nr); 377 378 reply(mp, OK); 379 } 380 381 static void do_reserve(message *mp) 382 { 383 struct rs_pci *aclp; 384 int r, devind; 385 386 devind= mp->m1_i1; 387 388 aclp= find_acl(mp->m_source); 389 390 mp->m_type= pci_reserve_a(devind, mp->m_source, aclp); 391 r= ipc_send(mp->m_source, mp); 392 if (r != 0) 393 { 394 printf("do_reserve: unable to send to %d: %d\n", 395 mp->m_source, r); 396 } 397 } 398 399 static void do_attr_r8(mp) 400 message *mp; 401 { 402 int r, devind, port; 403 u8_t v; 404 405 devind= mp->m2_i1; 406 port= mp->m2_i2; 407 408 r= pci_attr_r8_s(devind, port, &v); 409 if (r != OK) 410 { 411 printf( 412 "pci:do_attr_r8: pci_attr_r8_s(%d, %d, ...) failed: %d\n", 413 devind, port, r); 414 } 415 mp->m2_l1= v; 416 mp->m_type= r; 417 r= ipc_send(mp->m_source, mp); 418 if (r != 0) 419 { 420 printf("do_attr_r8: unable to send to %d: %d\n", 421 mp->m_source, r); 422 } 423 } 424 425 static void do_attr_r16(mp) 426 message *mp; 427 { 428 int r, devind, port; 429 u32_t v; 430 431 devind= mp->m2_i1; 432 port= mp->m2_i2; 433 434 v= pci_attr_r16(devind, port); 435 mp->m2_l1= v; 436 mp->m_type= OK; 437 r= ipc_send(mp->m_source, mp); 438 if (r != 0) 439 { 440 printf("do_attr_r16: unable to send to %d: %d\n", 441 mp->m_source, r); 442 } 443 } 444 445 static void do_attr_r32(mp) 446 message *mp; 447 { 448 int r, devind, port; 449 u32_t v; 450 451 devind= mp->m2_i1; 452 port= mp->m2_i2; 453 454 r= pci_attr_r32_s(devind, port, &v); 455 if (r != OK) 456 { 457 printf( 458 "pci:do_attr_r32: pci_attr_r32_s(%d, %d, ...) failed: %d\n", 459 devind, port, r); 460 } 461 mp->m2_l1= v; 462 mp->m_type= OK; 463 r= ipc_send(mp->m_source, mp); 464 if (r != 0) 465 { 466 printf("do_attr_r32: unable to send to %d: %d\n", 467 mp->m_source, r); 468 } 469 } 470 471 static void do_attr_w8(mp) 472 message *mp; 473 { 474 int r, devind, port; 475 u8_t v; 476 477 devind= mp->m2_i1; 478 port= mp->m2_i2; 479 v= mp->m2_l1; 480 481 pci_attr_w8(devind, port, v); 482 mp->m_type= OK; 483 r= ipc_send(mp->m_source, mp); 484 if (r != 0) 485 { 486 printf("do_attr_w8: unable to send to %d: %d\n", 487 mp->m_source, r); 488 } 489 } 490 491 static void do_attr_w16(mp) 492 message *mp; 493 { 494 int r, devind, port; 495 u16_t v; 496 497 devind= mp->m2_i1; 498 port= mp->m2_i2; 499 v= mp->m2_l1; 500 501 pci_attr_w16(devind, port, v); 502 mp->m_type= OK; 503 r= ipc_send(mp->m_source, mp); 504 if (r != 0) 505 { 506 printf("do_attr_w16: unable to send to %d: %d\n", 507 mp->m_source, r); 508 } 509 } 510 511 static void do_attr_w32(mp) 512 message *mp; 513 { 514 int r, devind, port; 515 u32_t v; 516 517 devind= mp->m2_i1; 518 port= mp->m2_i2; 519 v= mp->m2_l1; 520 521 pci_attr_w32(devind, port, v); 522 mp->m_type= OK; 523 r= ipc_send(mp->m_source, mp); 524 if (r != 0) 525 { 526 printf("do_attr_w32: unable to send to %d: %d\n", 527 mp->m_source, r); 528 } 529 } 530 531 static void do_get_bar(mp) 532 message *mp; 533 { 534 int r, devind, port, ioflag; 535 u32_t base, size; 536 537 devind= mp->m_lsys_pci_busc_get_bar.devind; 538 port= mp->m_lsys_pci_busc_get_bar.port; 539 540 mp->m_type= pci_get_bar_s(devind, port, &base, &size, &ioflag); 541 542 if (mp->m_type == OK) 543 { 544 mp->m_pci_lsys_busc_get_bar.base= base; 545 mp->m_pci_lsys_busc_get_bar.size= size; 546 mp->m_pci_lsys_busc_get_bar.flags= ioflag; 547 } 548 549 r= ipc_send(mp->m_source, mp); 550 if (r != 0) 551 { 552 printf("do_get_bar: unable to send to %d: %d\n", 553 mp->m_source, r); 554 } 555 } 556 557 static void do_rescan_bus(mp) 558 message *mp; 559 { 560 int r, busnr; 561 562 busnr= mp->m2_i1; 563 564 pci_rescan_bus(busnr); 565 mp->m_type= OK; 566 r= ipc_send(mp->m_source, mp); 567 if (r != 0) 568 { 569 printf("do_rescan_bus: unable to send to %d: %d\n", 570 mp->m_source, r); 571 } 572 } 573 574 575 static void reply(mp, result) 576 message *mp; 577 int result; 578 { 579 int r; 580 message m; 581 582 m.m_type= result; 583 r= ipc_send(mp->m_source, &m); 584 if (r != 0) 585 printf("reply: unable to send to %d: %d\n", mp->m_source, r); 586 } 587 588 589 static struct rs_pci *find_acl(endpoint) 590 int endpoint; 591 { 592 int i; 593 594 /* Find ACL entry for caller */ 595 for (i= 0; i<NR_DRIVERS; i++) 596 { 597 if (!pci_acl[i].inuse) 598 continue; 599 if (pci_acl[i].acl.rsp_endpoint == endpoint) 600 return &pci_acl[i].acl; 601 } 602 return NULL; 603 } 604