Changeset cb41a5e in mainline for uspace/srv/devmap/devmap.c
- Timestamp:
- 2009-05-21T07:03:38Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a095d20
- Parents:
- 2246de6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devmap/devmap.c
r2246de6 rcb41a5e 49 49 #define NAME "devmap" 50 50 51 /** Representation of device driver. 52 * 53 * Each driver is responsible for a set of devices. 54 * 55 */ 56 typedef struct { 57 /** Pointers to previous and next drivers in linked list */ 58 link_t drivers; 59 /** Pointer to the linked list of devices controlled by this driver */ 60 link_t devices; 61 /** Phone asociated with this driver */ 62 ipcarg_t phone; 63 /** Device driver name */ 64 char *name; 65 /** Futex for list of devices owned by this driver */ 66 atomic_t devices_futex; 67 } devmap_driver_t; 68 69 /** Info about registered device 70 * 71 */ 72 typedef struct { 73 /** Pointer to the previous and next device in the list of all devices */ 74 link_t devices; 75 /** Pointer to the previous and next device in the list of devices 76 owned by one driver */ 77 link_t driver_devices; 78 /** Unique device identifier */ 79 dev_handle_t handle; 80 /** Device name */ 81 char *name; 82 /** Device driver handling this device */ 83 devmap_driver_t *driver; 84 } devmap_device_t; 85 51 86 /** Pending lookup structure. */ 52 87 typedef struct { … … 71 106 static atomic_t create_handle_futex = FUTEX_INITIALIZER; 72 107 73 static int devmap_create_handle(void) 74 { 75 static int last_handle = 0; 76 int handle; 77 108 static dev_handle_t last_handle = 0; 109 110 static dev_handle_t devmap_create_handle(void) 111 { 78 112 /* TODO: allow reusing old handles after their unregistration 79 113 * and implement some version of LRU algorithm … … 82 116 /* FIXME: overflow */ 83 117 futex_down(&create_handle_futex); 84 85 last_handle += 1; 86 handle = last_handle; 87 118 last_handle++; 88 119 futex_up(&create_handle_futex); 89 120 90 return handle; 91 } 92 93 94 /** Initialize device mapper. 95 * 96 * 97 */ 98 static int devmap_init() 99 { 100 /* TODO: */ 101 102 return EOK; 121 return last_handle; 103 122 } 104 123 … … 130 149 * 131 150 */ 132 static devmap_device_t *devmap_device_find_handle( int handle)151 static devmap_device_t *devmap_device_find_handle(dev_handle_t handle) 133 152 { 134 153 futex_down(&devices_list_futex); … … 298 317 futex_down(&drivers_list_futex); 299 318 300 ipc_hangup(driver->phone); 301 302 /* remove it from list of drivers */ 319 if (driver->phone != 0) 320 ipc_hangup(driver->phone); 321 322 /* Remove it from list of drivers */ 303 323 list_remove(&(driver->drivers)); 304 324 305 /* unregister all its devices */ 306 325 /* Unregister all its devices */ 307 326 futex_down(&devices_list_futex); 308 327 futex_down(&(driver->devices_futex)); … … 319 338 320 339 /* free name and driver */ 321 if ( NULL != driver->name)340 if (driver->name != NULL) 322 341 free(driver->name); 323 342 … … 455 474 * Get handle from request 456 475 */ 457 int handle = IPC_GET_ARG2(*call);476 dev_handle_t handle = IPC_GET_ARG2(*call); 458 477 devmap_device_t *dev = devmap_device_find_handle(handle); 459 478 460 if ( NULL == dev) {479 if ((dev == NULL) || (dev->driver == NULL) || (dev->driver->phone == 0)) { 461 480 ipc_answer_0(callid, ENOENT); 462 481 return; 463 482 } 464 483 465 ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle),484 ipc_forward_fast(callid, dev->driver->phone, dev->handle, 466 485 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 467 486 } … … 496 515 * Allocate buffer for device name. 497 516 */ 498 char *name = (char *) malloc(size );517 char *name = (char *) malloc(size + 1); 499 518 if (name == NULL) { 500 519 ipc_answer_0(callid, ENOMEM); … … 550 569 * 551 570 */ 552 static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall) 571 static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall) 553 572 { 554 573 const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall)); … … 578 597 579 598 /* TODO: send name in response */ 599 } 600 601 static void devmap_get_count(ipc_callid_t iid, ipc_call_t *icall) 602 { 603 futex_down(&devices_list_futex); 604 ipc_answer_1(iid, EOK, list_count(&devices_list)); 605 futex_up(&devices_list_futex); 606 } 607 608 static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall) 609 { 610 futex_down(&devices_list_futex); 611 612 ipc_callid_t callid; 613 size_t size; 614 if (!ipc_data_read_receive(&callid, &size)) { 615 ipc_answer_0(callid, EREFUSED); 616 ipc_answer_0(iid, EREFUSED); 617 return; 618 } 619 620 if ((size % sizeof(dev_desc_t)) != 0) { 621 ipc_answer_0(callid, EINVAL); 622 ipc_answer_0(iid, EREFUSED); 623 return; 624 } 625 626 count_t count = size / sizeof(dev_desc_t); 627 dev_desc_t *desc = (dev_desc_t *) malloc(size); 628 if (desc == NULL) { 629 ipc_answer_0(callid, ENOMEM); 630 ipc_answer_0(iid, EREFUSED); 631 return; 632 } 633 634 count_t pos = 0; 635 link_t *item = devices_list.next; 636 637 while ((item != &devices_list) && (pos < count)) { 638 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 639 640 desc[pos].handle = device->handle; 641 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 642 pos++; 643 item = item->next; 644 } 645 646 ipcarg_t retval = ipc_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t)); 647 if (retval != EOK) { 648 ipc_answer_0(iid, EREFUSED); 649 free(desc); 650 return; 651 } 652 653 free(desc); 654 655 futex_up(&devices_list_futex); 656 657 ipc_answer_1(iid, EOK, pos); 658 } 659 660 /** Initialize device mapper. 661 * 662 * 663 */ 664 static bool devmap_init() 665 { 666 /* Create NULL device entry */ 667 devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); 668 if (device == NULL) 669 return false; 670 671 device->name = str_dup("null"); 672 if (device->name == NULL) { 673 free(device); 674 return false; 675 } 676 677 list_initialize(&(device->devices)); 678 list_initialize(&(device->driver_devices)); 679 680 futex_down(&devices_list_futex); 681 682 /* Get unique device handle */ 683 device->handle = devmap_create_handle(); 684 device->driver = NULL; 685 686 /* Insert device into list of all devices */ 687 list_append(&device->devices, &devices_list); 688 689 futex_up(&devices_list_futex); 690 691 return true; 580 692 } 581 693 … … 622 734 break; 623 735 case DEVMAP_DEVICE_GET_NAME: 624 devmap_get_ handle(callid, &call);736 devmap_get_name(callid, &call); 625 737 break; 626 738 default: … … 661 773 break; 662 774 case DEVMAP_DEVICE_GET_NAME: 663 /* TODO */664 775 devmap_get_name(callid, &call); 776 break; 777 case DEVMAP_DEVICE_GET_COUNT: 778 devmap_get_count(callid, &call); 779 break; 780 case DEVMAP_DEVICE_GET_DEVICES: 781 devmap_get_devices(callid, &call); 665 782 break; 666 783 default: … … 701 818 printf(NAME ": HelenOS Device Mapper\n"); 702 819 703 if ( devmap_init() != 0) {820 if (!devmap_init()) { 704 821 printf(NAME ": Error while initializing service\n"); 705 822 return -1;
Note:
See TracChangeset
for help on using the changeset viewer.