Changeset 76b5a95c in mainline for uspace/lib


Ignore:
Timestamp:
2011-03-23T20:53:30Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
71af5a4
Parents:
5716e9a (diff), ab10b842 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace/lib
Files:
1 added
28 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r5716e9a r76b5a95c  
    9191        generic/loader.c \
    9292        generic/getopt.c \
    93         generic/adt/list.o \
    94         generic/adt/hash_table.o \
     93        generic/adt/list.c \
     94        generic/adt/hash_table.c \
    9595        generic/adt/dynamic_fifo.c \
    9696        generic/adt/measured_strings.c \
  • uspace/lib/c/arch/abs32le/_link.ld.in

    r5716e9a r76b5a95c  
    4444        } :data
    4545       
    46         . = ALIGN(0x1000);
    47        
    48         _heap = .;
    49        
    5046        /DISCARD/ : {
    5147                *(*);
  • uspace/lib/c/arch/amd64/_link.ld.in

    r5716e9a r76b5a95c  
    55        text PT_LOAD FLAGS(5);
    66        data PT_LOAD FLAGS(6);
     7        debug PT_NOTE;
    78}
    89
     
    1314                *(.init);
    1415        } :text
     16       
    1517        .text : {
    1618                *(.text);
    1719                *(.rodata*);
    1820        } :text
    19 
     21       
    2022        . = . + 0x1000;
    21 
     23       
    2224        .data : {
    2325                *(.data);
    2426        } :data
     27       
    2528        .tdata : {
    2629                _tdata_start = .;
     
    3134                _tbss_end = .;
    3235        } :data
     36       
    3337        _tls_alignment = ALIGNOF(.tdata);
     38       
    3439        .bss : {
    3540                *(COMMON);
    3641                *(.bss);
    3742        } :data
    38 
    39         . = ALIGN(0x1000);
    40         _heap = .;
     43       
     44#ifdef CONFIG_LINE_DEBUG
     45        .comment 0 : { *(.comment); } :debug
     46        .debug_abbrev 0 : { *(.debug_abbrev); } :debug
     47        .debug_aranges 0 : { *(.debug_aranges); } :debug
     48        .debug_info 0 : { *(.debug_info); } :debug
     49        .debug_line 0 : { *(.debug_line); } :debug
     50        .debug_loc 0 : { *(.debug_loc); } :debug
     51        .debug_pubnames 0 : { *(.debug_pubnames); } :debug
     52        .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
     53        .debug_ranges 0 : { *(.debug_ranges); } :debug
     54        .debug_str 0 : { *(.debug_str); } :debug
     55#endif
    4156       
    4257        /DISCARD/ : {
    4358                *(*);
    4459        }
    45 
    4660}
  • uspace/lib/c/arch/arm32/_link.ld.in

    r5716e9a r76b5a95c  
    99SECTIONS {
    1010        . = 0x1000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    14         } : text
     14        } :text
     15       
    1516        .text : {
    1617                *(.text);
    17         *(.rodata*);
     18                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x1000;
    21 
     22       
    2223        .data : {
    2324                *(.opd);
     
    2526                *(.sdata);
    2627        } :data
     28       
    2729        .tdata : {
    2830                _tdata_start = .;
     
    3335                _tbss_end = .;
    3436        } :data
     37       
    3538        _tls_alignment = ALIGNOF(.tdata);
     39       
    3640        .bss : {
    3741                *(.sbss);
    3842                *(.scommon);
    39         *(COMMON);
    40         *(.bss);
     43                *(COMMON);
     44                *(.bss);
    4145        } :data
    42        
    43         . = ALIGN(0x1000);
    44         _heap = .;
    4546       
    4647        /DISCARD/ : {
    4748                *(*);
    4849        }
    49 
    5050}
  • uspace/lib/c/arch/ia32/_link.ld.in

    r5716e9a r76b5a95c  
    55        text PT_LOAD FLAGS(5);
    66        data PT_LOAD FLAGS(6);
     7        debug PT_NOTE;
    78}
    89
     
    4243        } :data
    4344       
    44         . = ALIGN(0x1000);
    45        
    46         _heap = .;
     45#ifdef CONFIG_LINE_DEBUG
     46        .comment 0 : { *(.comment); } :debug
     47        .debug_abbrev 0 : { *(.debug_abbrev); } :debug
     48        .debug_aranges 0 : { *(.debug_aranges); } :debug
     49        .debug_info 0 : { *(.debug_info); } :debug
     50        .debug_line 0 : { *(.debug_line); } :debug
     51        .debug_loc 0 : { *(.debug_loc); } :debug
     52        .debug_pubnames 0 : { *(.debug_pubnames); } :debug
     53        .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
     54        .debug_ranges 0 : { *(.debug_ranges); } :debug
     55        .debug_str 0 : { *(.debug_str); } :debug
     56#endif
    4757       
    4858        /DISCARD/ : {
  • uspace/lib/c/arch/ia64/_link.ld.in

    r5716e9a r76b5a95c  
    99SECTIONS {
    1010        . = 0x4000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    14         } : text
     14        } :text
     15       
    1516        .text : {
    1617                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x4000;
    21 
     22       
    2223        .got : {
    2324                _gp = .;
    2425                *(.got*);
    25         } :data
     26        } :data
     27       
    2628        .data : {
    2729                *(.opd);
     
    2931                *(.sdata);
    3032        } :data
     33       
    3134        .tdata : {
    3235                _tdata_start = .;
     
    3740                _tbss_end = .;
    3841        } :data
     42       
    3943        _tls_alignment = ALIGNOF(.tdata);
     44       
    4045        .bss : {
    4146                *(.sbss);
     
    4449                *(.bss);
    4550        } :data
    46 
    47         . = ALIGN(0x4000);
    48         _heap = .;
    49  
     51       
    5052        /DISCARD/ : {
    5153                *(*);
    52         }
     54        }
    5355}
  • uspace/lib/c/arch/mips32/_link.ld.in

    r5716e9a r76b5a95c  
    1313                *(.init);
    1414        } :text
     15       
    1516        .text : {
    16                 *(.text);
     17                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x4000;
    21 
     22       
    2223        .data : {
    2324                *(.data);
    2425                *(.data.rel*);
    2526        } :data
    26 
     27       
    2728        .got : {
    2829                _gp = .;
    2930                *(.got);
    3031        } :data
    31 
     32       
    3233        .tdata : {
    3334                _tdata_start = .;
    3435                *(.tdata);
    3536                _tdata_end = .;
     37        } :data
     38       
     39        .tbss : {
    3640                _tbss_start = .;
    3741                *(.tbss);
    3842                _tbss_end = .;
    3943        } :data
    40         _tls_alignment = ALIGNOF(.tdata);
    41 
     44       
     45        _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
     46       
    4247        .sbss : {
    4348                *(.scommon);
    4449                *(.sbss);
    45         }       
     50        }
     51       
    4652        .bss : {
    4753                *(.bss);
    4854                *(COMMON);
    4955        } :data
    50 
    51         . = ALIGN(0x4000);
    52         _heap = .;
    53 
     56       
    5457        /DISCARD/ : {
    5558                *(*);
  • uspace/lib/c/arch/mips32/src/entry.s

    r5716e9a r76b5a95c  
    2929.text
    3030.section .init, "ax"
     31
    3132.global __entry
    32 .global __entry_driver
     33
    3334.set noreorder
    3435.option pic2
     
    5758        nop
    5859.end
    59 
    60 # Alignment of output section data to 0x4000
    61 .section .data
    62 .align 14
  • uspace/lib/c/arch/ppc32/_link.ld.in

    r5716e9a r76b5a95c  
    99SECTIONS {
    1010        . = 0x1000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    1414        } :text
     15       
    1516        .text : {
    1617                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x1000;
    21 
     22       
    2223        .data : {
    2324                *(.data);
    2425                *(.sdata);
    2526        } :data
     27       
    2628        .tdata : {
    2729                _tdata_start = .;
     
    3234                _tbss_end = .;
    3335        } :data
     36       
    3437        _tls_alignment = ALIGNOF(.tdata);
     38       
    3539        .bss : {
    3640                *(.sbss);
     
    3842                *(.bss);
    3943        } :data
    40 
    41         . = ALIGN(0x1000);
    42         _heap = .;
    4344       
    4445        /DISCARD/ : {
    4546                *(*);
    4647        }
    47 
    4848}
  • uspace/lib/c/arch/sparc64/_link.ld.in

    r5716e9a r76b5a95c  
    99SECTIONS {
    1010        . = 0x4000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    1414        } :text
     15       
    1516        .text : {
    1617                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x4000;
    21 
     22       
    2223        .got : {
    2324                 _gp = .;
    2425                 *(.got*);
    2526        } :data
     27       
    2628        .data : {
    2729                *(.data);
    2830                *(.sdata);
    2931        } :data
     32       
    3033        .tdata : {
    3134                _tdata_start = .;
     
    3639                _tbss_end = .;
    3740        } :data
     41       
    3842        _tls_alignment = ALIGNOF(.tdata);
     43       
    3944        .bss : {
    4045                *(.sbss);
     
    4247                *(.bss);
    4348        } :data
    44 
    45         . = ALIGN(0x4000);
    46         _heap = .;
    4749       
    4850        /DISCARD/ : {
    4951                *(*);
    5052        }
    51 
    5253}
  • uspace/lib/c/generic/as.c

    r5716e9a r76b5a95c  
    4040#include <bitops.h>
    4141#include <malloc.h>
    42 
    43 /** Last position allocated by as_get_mappable_page */
    44 static uintptr_t last_allocated = 0;
     42#include "private/libc.h"
    4543
    4644/** Create address space area.
     
    103101}
    104102
    105 /** Return pointer to some unmapped area, where fits new as_area
     103/** Return pointer to unmapped address space area
    106104 *
    107105 * @param size Requested size of the allocation.
    108106 *
    109  * @return pointer to the beginning
     107 * @return Pointer to the beginning of unmapped address space area.
    110108 *
    111109 */
    112110void *as_get_mappable_page(size_t size)
    113111{
    114         if (size == 0)
    115                 return NULL;
    116        
    117         size_t sz = 1 << (fnzb(size - 1) + 1);
    118         if (last_allocated == 0)
    119                 last_allocated = get_max_heap_addr();
    120        
    121         /*
    122          * Make sure we allocate from naturally aligned address.
    123          */
    124         uintptr_t res = ALIGN_UP(last_allocated, sz);
    125         last_allocated = res + ALIGN_UP(size, PAGE_SIZE);
    126        
    127         return ((void *) res);
     112        return (void *) __SYSCALL2(SYS_AS_GET_UNMAPPED_AREA,
     113            (sysarg_t) __entry, (sysarg_t) size);
    128114}
    129115
  • uspace/lib/c/generic/async.c

    r5716e9a r76b5a95c  
    430430       
    431431        fid_t fid = fibril_create(notification_fibril, msg);
     432        if (fid == 0) {
     433                free(msg);
     434                futex_up(&async_futex);
     435                return false;
     436        }
     437       
    432438        fibril_add_ready(fid);
    433439       
     
    681687        conn->wdata.fid = fibril_create(connection_fibril, conn);
    682688       
    683         if (!conn->wdata.fid) {
     689        if (conn->wdata.fid == 0) {
    684690                free(conn);
     691               
    685692                if (callid)
    686693                        ipc_answer_0(callid, ENOMEM);
     694               
    687695                return (uintptr_t) NULL;
    688696        }
     
    853861{
    854862        fid_t fid = fibril_create(async_manager_fibril, NULL);
    855         fibril_add_manager(fid);
     863        if (fid != 0)
     864                fibril_add_manager(fid);
    856865}
    857866
  • uspace/lib/c/generic/devman.c

    r5716e9a r76b5a95c  
    123123}
    124124
    125 static int devman_send_match_id(int phone, match_id_t *match_id) \
    126 {
    127         ipc_call_t answer;
    128         aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
    129         int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id));
     125static int devman_send_match_id(int phone, match_id_t *match_id)
     126{
     127        ipc_call_t answer;
     128
     129        aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
     130            &answer);
     131        int retval = async_data_write_start(phone, match_id->id,
     132            str_size(match_id->id));
     133
    130134        async_wait_for(req, NULL);
    131135        return retval;
     
    133137
    134138
    135 static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 
     139static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
    136140{
    137141        link_t *link = match_ids->ids.next;
    138142        match_id_t *match_id = NULL;
    139143        int ret = EOK;
    140        
     144
    141145        while (link != &match_ids->ids) {
    142146                match_id = list_get_instance(link, match_id_t, link);
    143                 if (EOK != (ret = devman_send_match_id(phone, match_id)))
    144                 {
    145                         printf("Driver failed to send match id, error number = %d\n", ret);
    146                         return ret;                     
    147                 }
     147                ret = devman_send_match_id(phone, match_id);
     148                if (ret != EOK) {
     149                        printf("Driver failed to send match id, error %d\n",
     150                            ret);
     151                        return ret;
     152                }
     153
    148154                link = link->next;
    149155        }
    150         return ret;     
    151 }
    152 
    153 int devman_child_device_register(
    154         const char *name, match_id_list_t *match_ids, devman_handle_t parent_handle, devman_handle_t *handle)
    155 {               
     156
     157        return ret;
     158}
     159
     160/** Add function to a device.
     161 *
     162 * Request devman to add a new function to the specified device owned by
     163 * this driver task.
     164 *
     165 * @param name          Name of the new function
     166 * @param ftype         Function type, fun_inner or fun_exposed
     167 * @param match_ids     Match IDs (should be empty for fun_exposed)
     168 * @param devh          Devman handle of the device
     169 * @param funh          Place to store handle of the new function
     170 *
     171 * @return              EOK on success or negative error code.
     172 */
     173int devman_add_function(const char *name, fun_type_t ftype,
     174    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
     175{
    156176        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
     177        int fun_handle;
    157178       
    158179        if (phone < 0)
     
    161182        async_serialize_start();
    162183       
    163         int match_count = list_count(&match_ids->ids); 
    164         ipc_call_t answer;
    165         aid_t req = async_send_2(phone, DEVMAN_ADD_CHILD_DEVICE, parent_handle, match_count, &answer);
     184        int match_count = list_count(&match_ids->ids);
     185        ipc_call_t answer;
     186
     187        aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
     188            devh, match_count, &answer);
    166189
    167190        sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     
    178201        async_serialize_end();
    179202       
    180         if (retval != EOK) {
    181                 if (handle != NULL) {
    182                         *handle = -1;
    183                 }
    184                 return retval;
    185         }       
    186        
    187         if (handle != NULL)
    188                 *handle = (int) IPC_GET_ARG1(answer);   
    189                
    190         return retval;
    191 }
    192 
    193 int devman_add_device_to_class(devman_handle_t devman_handle, const char *class_name)
     203        if (retval == EOK)
     204                fun_handle = (int) IPC_GET_ARG1(answer);
     205        else
     206                fun_handle = -1;
     207       
     208        *funh = fun_handle;
     209
     210        return retval;
     211}
     212
     213int devman_add_device_to_class(devman_handle_t devman_handle,
     214    const char *class_name)
    194215{
    195216        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
     
    200221        async_serialize_start();
    201222        ipc_call_t answer;
    202         aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, devman_handle, &answer);
    203        
    204         sysarg_t retval = async_data_write_start(phone, class_name, str_size(class_name));
     223        aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
     224            devman_handle, &answer);
     225       
     226        sysarg_t retval = async_data_write_start(phone, class_name,
     227            str_size(class_name));
    205228        if (retval != EOK) {
    206229                async_wait_for(req, NULL);
     
    212235        async_serialize_end();
    213236       
    214         return retval; 
     237        return retval;
    215238}
    216239
     
    265288}
    266289
    267 int devman_device_get_handle(const char *pathname, devman_handle_t *handle, unsigned int flags)
     290int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
     291    unsigned int flags)
    268292{
    269293        int phone = devman_get_phone(DEVMAN_CLIENT, flags);
     
    278302            &answer);
    279303       
    280         sysarg_t retval = async_data_write_start(phone, pathname, str_size(pathname));
     304        sysarg_t retval = async_data_write_start(phone, pathname,
     305            str_size(pathname));
    281306        if (retval != EOK) {
    282307                async_wait_for(req, NULL);
  • uspace/lib/c/generic/fibril.c

    r5716e9a r76b5a95c  
    115115        fibril->retval = 0;
    116116        fibril->flags = 0;
     117       
     118        fibril->waits_for = NULL;
    117119       
    118120        return fibril;
     
    276278        fibril->arg = arg;
    277279
    278         fibril->waits_for = NULL;
    279        
    280280        context_save(&fibril->ctx);
    281281        context_set(&fibril->ctx, FADDR(fibril_main), fibril->stack,
  • uspace/lib/c/generic/loader.c

    r5716e9a r76b5a95c  
    160160        int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
    161161        if (rc != EOK) {
     162                free(pa);
    162163                async_wait_for(req, NULL);
    163164                return rc;
  • uspace/lib/c/generic/malloc.c

    r5716e9a r76b5a95c  
    4747#include "private/malloc.h"
    4848
    49 /* Magic used in heap headers. */
    50 #define HEAP_BLOCK_HEAD_MAGIC  0xBEEF0101
    51 
    52 /* Magic used in heap footers. */
    53 #define HEAP_BLOCK_FOOT_MAGIC  0xBEEF0202
    54 
    55 /** Allocation alignment (this also covers the alignment of fields
    56     in the heap header and footer) */
     49/** Magic used in heap headers. */
     50#define HEAP_BLOCK_HEAD_MAGIC  UINT32_C(0xBEEF0101)
     51
     52/** Magic used in heap footers. */
     53#define HEAP_BLOCK_FOOT_MAGIC  UINT32_C(0xBEEF0202)
     54
     55/** Magic used in heap descriptor. */
     56#define HEAP_AREA_MAGIC  UINT32_C(0xBEEFCAFE)
     57
     58/** Allocation alignment.
     59 *
     60 * This also covers the alignment of fields
     61 * in the heap header and footer.
     62 *
     63 */
    5764#define BASE_ALIGN  16
    5865
    59 /**
    60  * Either 4 * 256M on 32-bit architecures or 16 * 256M on 64-bit architectures
    61  */
    62 #define MAX_HEAP_SIZE  (sizeof(uintptr_t) << 28)
    63 
    64 /**
    65  *
    66  */
    67 #define STRUCT_OVERHEAD  (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    68 
    69 /**
    70  * Calculate real size of a heap block (with header and footer)
     66/** Overhead of each heap block. */
     67#define STRUCT_OVERHEAD \
     68        (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
     69
     70/** Calculate real size of a heap block.
     71 *
     72 * Add header and footer size.
     73 *
    7174 */
    7275#define GROSS_SIZE(size)  ((size) + STRUCT_OVERHEAD)
    7376
    74 /**
    75  * Calculate net size of a heap block (without header and footer)
     77/** Calculate net size of a heap block.
     78 *
     79 * Subtract header and footer size.
     80 *
    7681 */
    7782#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
     83
     84/** Get first block in heap area.
     85 *
     86 */
     87#define AREA_FIRST_BLOCK(area) \
     88        (ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN))
     89
     90/** Get footer in heap block.
     91 *
     92 */
     93#define BLOCK_FOOT(head) \
     94        ((heap_block_foot_t *) \
     95            (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))
     96
     97/** Heap area.
     98 *
     99 * The memory managed by the heap allocator is divided into
     100 * multiple discontinuous heaps. Each heap is represented
     101 * by a separate address space area which has this structure
     102 * at its very beginning.
     103 *
     104 */
     105typedef struct heap_area {
     106        /** Start of the heap area (including this structure)
     107         *
     108         * Aligned on page boundary.
     109         *
     110         */
     111        void *start;
     112       
     113        /** End of the heap area (aligned on page boundary) */
     114        void *end;
     115       
     116        /** Next heap area */
     117        struct heap_area *next;
     118       
     119        /** A magic value */
     120        uint32_t magic;
     121} heap_area_t;
    78122
    79123/** Header of a heap block
     
    87131        bool free;
    88132       
     133        /** Heap area this block belongs to */
     134        heap_area_t *area;
     135       
    89136        /* A magic value to detect overwrite of heap header */
    90137        uint32_t magic;
     
    102149} heap_block_foot_t;
    103150
    104 /** Linker heap symbol */
    105 extern char _heap;
     151/** First heap area */
     152static heap_area_t *first_heap_area = NULL;
     153
     154/** Last heap area */
     155static heap_area_t *last_heap_area = NULL;
     156
     157/** Next heap block to examine (next fit algorithm) */
     158static heap_block_head_t *next = NULL;
    106159
    107160/** Futex for thread-safe heap manipulation */
    108161static futex_t malloc_futex = FUTEX_INITIALIZER;
    109162
    110 /** Address of heap start */
    111 static void *heap_start = 0;
    112 
    113 /** Address of heap end */
    114 static void *heap_end = 0;
    115 
    116 /** Maximum heap size */
    117 static size_t max_heap_size = (size_t) -1;
    118 
    119 /** Current number of pages of heap area */
    120 static size_t heap_pages = 0;
    121 
    122163/** Initialize a heap block
    123164 *
    124  * Fills in the structures related to a heap block.
     165 * Fill in the structures related to a heap block.
    125166 * Should be called only inside the critical section.
    126167 *
     
    128169 * @param size Size of the block including the header and the footer.
    129170 * @param free Indication of a free block.
    130  *
    131  */
    132 static void block_init(void *addr, size_t size, bool free)
     171 * @param area Heap area the block belongs to.
     172 *
     173 */
     174static void block_init(void *addr, size_t size, bool free, heap_area_t *area)
    133175{
    134176        /* Calculate the position of the header and the footer */
    135177        heap_block_head_t *head = (heap_block_head_t *) addr;
    136         heap_block_foot_t *foot =
    137             (heap_block_foot_t *) (addr + size - sizeof(heap_block_foot_t));
    138178       
    139179        head->size = size;
    140180        head->free = free;
     181        head->area = area;
    141182        head->magic = HEAP_BLOCK_HEAD_MAGIC;
     183       
     184        heap_block_foot_t *foot = BLOCK_FOOT(head);
    142185       
    143186        foot->size = size;
     
    160203        assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    161204       
    162         heap_block_foot_t *foot =
    163             (heap_block_foot_t *) (addr + head->size - sizeof(heap_block_foot_t));
     205        heap_block_foot_t *foot = BLOCK_FOOT(head);
    164206       
    165207        assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     
    167209}
    168210
    169 /** Increase the heap area size
    170  *
    171  * Should be called only inside the critical section.
    172  *
    173  * @param size Number of bytes to grow the heap by.
    174  *
    175  */
    176 static bool grow_heap(size_t size)
     211/** Check a heap area structure
     212 *
     213 * @param addr Address of the heap area.
     214 *
     215 */
     216static void area_check(void *addr)
     217{
     218        heap_area_t *area = (heap_area_t *) addr;
     219       
     220        assert(area->magic == HEAP_AREA_MAGIC);
     221        assert(area->start < area->end);
     222        assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
     223        assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
     224}
     225
     226/** Create new heap area
     227 *
     228 * @param start Preffered starting address of the new area.
     229 * @param size  Size of the area.
     230 *
     231 */
     232static bool area_create(size_t size)
     233{
     234        void *start = as_get_mappable_page(size);
     235        if (start == NULL)
     236                return false;
     237       
     238        /* Align the heap area on page boundary */
     239        void *astart = (void *) ALIGN_UP((uintptr_t) start, PAGE_SIZE);
     240        size_t asize = ALIGN_UP(size, PAGE_SIZE);
     241       
     242        astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
     243        if (astart == (void *) -1)
     244                return false;
     245       
     246        heap_area_t *area = (heap_area_t *) astart;
     247       
     248        area->start = astart;
     249        area->end = (void *)
     250            ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);
     251        area->next = NULL;
     252        area->magic = HEAP_AREA_MAGIC;
     253       
     254        void *block = (void *) AREA_FIRST_BLOCK(area);
     255        size_t bsize = (size_t) (area->end - block);
     256       
     257        block_init(block, bsize, true, area);
     258       
     259        if (last_heap_area == NULL) {
     260                first_heap_area = area;
     261                last_heap_area = area;
     262        } else {
     263                last_heap_area->next = area;
     264                last_heap_area = area;
     265        }
     266       
     267        return true;
     268}
     269
     270/** Try to enlarge a heap area
     271 *
     272 * @param area Heap area to grow.
     273 * @param size Gross size of item to allocate (bytes).
     274 *
     275 */
     276static bool area_grow(heap_area_t *area, size_t size)
    177277{
    178278        if (size == 0)
     279                return true;
     280       
     281        area_check(area);
     282       
     283        size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,
     284            PAGE_SIZE);
     285       
     286        /* New heap area size */
     287        void *end = (void *)
     288            ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN);
     289       
     290        /* Check for overflow */
     291        if (end < area->start)
    179292                return false;
    180 
    181         if ((heap_start + size < heap_start) || (heap_end + size < heap_end))
     293       
     294        /* Resize the address space area */
     295        int ret = as_area_resize(area->start, asize, 0);
     296        if (ret != EOK)
    182297                return false;
    183298       
    184         size_t heap_size = (size_t) (heap_end - heap_start);
    185        
    186         if ((max_heap_size != (size_t) -1) && (heap_size + size > max_heap_size))
    187                 return false;
    188        
    189         size_t pages = (size - 1) / PAGE_SIZE + 1;
    190        
    191         if (as_area_resize((void *) &_heap, (heap_pages + pages) * PAGE_SIZE, 0)
    192             == EOK) {
    193                 void *end = (void *) ALIGN_DOWN(((uintptr_t) &_heap) +
    194                     (heap_pages + pages) * PAGE_SIZE, BASE_ALIGN);
    195                 block_init(heap_end, end - heap_end, true);
    196                 heap_pages += pages;
    197                 heap_end = end;
     299        /* Add new free block */
     300        block_init(area->end, (size_t) (end - area->end), true, area);
     301       
     302        /* Update heap area parameters */
     303        area->end = end;
     304       
     305        return true;
     306}
     307
     308/** Try to enlarge any of the heap areas
     309 *
     310 * @param size Gross size of item to allocate (bytes).
     311 *
     312 */
     313static bool heap_grow(size_t size)
     314{
     315        if (size == 0)
    198316                return true;
    199         }
    200        
    201         return false;
    202 }
    203 
    204 /** Decrease the heap area
    205  *
    206  * Should be called only inside the critical section.
    207  *
    208  * @param size Number of bytes to shrink the heap by.
    209  *
    210  */
    211 static void shrink_heap(void)
    212 {
    213         // TODO
     317       
     318        /* First try to enlarge some existing area */
     319        heap_area_t *area;
     320        for (area = first_heap_area; area != NULL; area = area->next) {
     321                if (area_grow(area, size))
     322                        return true;
     323        }
     324       
     325        /* Eventually try to create a new area */
     326        return area_create(AREA_FIRST_BLOCK(size));
     327}
     328
     329/** Try to shrink heap space
     330 *
     331 * In all cases the next pointer is reset.
     332 *
     333 */
     334static void heap_shrink(void)
     335{
     336        next = NULL;
    214337}
    215338
     
    223346void __malloc_init(void)
    224347{
    225         if (!as_area_create((void *) &_heap, PAGE_SIZE,
    226             AS_AREA_WRITE | AS_AREA_READ))
     348        if (!area_create(PAGE_SIZE))
    227349                abort();
    228        
    229         heap_pages = 1;
    230         heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN);
    231         heap_end =
    232             (void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN);
    233        
    234         /* Make the entire area one large block. */
    235         block_init(heap_start, heap_end - heap_start, true);
    236 }
    237 
    238 /** Get maximum heap address
    239  *
    240  */
    241 uintptr_t get_max_heap_addr(void)
    242 {
    243         futex_down(&malloc_futex);
    244        
    245         if (max_heap_size == (size_t) -1)
    246                 max_heap_size =
    247                     max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
    248        
    249         uintptr_t max_heap_addr = (uintptr_t) heap_start + max_heap_size;
    250        
    251         futex_up(&malloc_futex);
    252        
    253         return max_heap_addr;
    254350}
    255351
     
    273369                /* Block big enough -> split. */
    274370                void *next = ((void *) cur) + size;
    275                 block_init(next, cur->size - size, true);
    276                 block_init(cur, size, false);
     371                block_init(next, cur->size - size, true, cur->area);
     372                block_init(cur, size, false, cur->area);
    277373        } else {
    278374                /* Block too small -> use as is. */
     
    281377}
    282378
    283 /** Allocate a memory block
     379/** Allocate memory from heap area starting from given block
    284380 *
    285381 * Should be called only inside the critical section.
    286  *
    287  * @param size  The size of the block to allocate.
    288  * @param align Memory address alignment.
    289  *
    290  * @return the address of the block or NULL when not enough memory.
    291  *
    292  */
    293 static void *malloc_internal(const size_t size, const size_t align)
    294 {
    295         if (align == 0)
    296                 return NULL;
    297        
    298         size_t falign = lcm(align, BASE_ALIGN);
    299         size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
    300        
    301         bool grown = false;
    302         void *result;
    303        
    304 loop:
    305         result = NULL;
    306         heap_block_head_t *cur = (heap_block_head_t *) heap_start;
    307        
    308         while ((result == NULL) && ((void *) cur < heap_end)) {
     382 * As a side effect this function also sets the current
     383 * pointer on successful allocation.
     384 *
     385 * @param area        Heap area where to allocate from.
     386 * @param first_block Starting heap block.
     387 * @param final_block Heap block where to finish the search
     388 *                    (may be NULL).
     389 * @param real_size   Gross number of bytes to allocate.
     390 * @param falign      Physical alignment of the block.
     391 *
     392 * @return Address of the allocated block or NULL on not enough memory.
     393 *
     394 */
     395static void *malloc_area(heap_area_t *area, heap_block_head_t *first_block,
     396    heap_block_head_t *final_block, size_t real_size, size_t falign)
     397{
     398        area_check((void *) area);
     399        assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area));
     400        assert((void *) first_block < area->end);
     401       
     402        heap_block_head_t *cur;
     403        for (cur = first_block; (void *) cur < area->end;
     404            cur = (heap_block_head_t *) (((void *) cur) + cur->size)) {
    309405                block_check(cur);
     406               
     407                /* Finish searching on the final block */
     408                if ((final_block != NULL) && (cur == final_block))
     409                        break;
    310410               
    311411                /* Try to find a block that is free and large enough. */
    312412                if ((cur->free) && (cur->size >= real_size)) {
    313                         /* We have found a suitable block.
    314                            Check for alignment properties. */
    315                         void *addr = ((void *) cur) + sizeof(heap_block_head_t);
    316                         void *aligned = (void *) ALIGN_UP(addr, falign);
     413                        /*
     414                         * We have found a suitable block.
     415                         * Check for alignment properties.
     416                         */
     417                        void *addr = (void *)
     418                            ((uintptr_t) cur + sizeof(heap_block_head_t));
     419                        void *aligned = (void *)
     420                            ALIGN_UP((uintptr_t) addr, falign);
    317421                       
    318422                        if (addr == aligned) {
    319423                                /* Exact block start including alignment. */
    320424                                split_mark(cur, real_size);
    321                                 result = addr;
     425                               
     426                                next = cur;
     427                                return addr;
    322428                        } else {
    323429                                /* Block start has to be aligned */
     
    325431                               
    326432                                if (cur->size >= real_size + excess) {
    327                                         /* The current block is large enough to fit
    328                                            data in including alignment */
    329                                         if ((void *) cur > heap_start) {
    330                                                 /* There is a block before the current block.
    331                                                    This previous block can be enlarged to compensate
    332                                                    for the alignment excess */
    333                                                 heap_block_foot_t *prev_foot =
    334                                                     ((void *) cur) - sizeof(heap_block_foot_t);
     433                                        /*
     434                                         * The current block is large enough to fit
     435                                         * data in (including alignment).
     436                                         */
     437                                        if ((void *) cur > (void *) AREA_FIRST_BLOCK(area)) {
     438                                                /*
     439                                                 * There is a block before the current block.
     440                                                 * This previous block can be enlarged to
     441                                                 * compensate for the alignment excess.
     442                                                 */
     443                                                heap_block_foot_t *prev_foot = (heap_block_foot_t *)
     444                                                    ((void *) cur - sizeof(heap_block_foot_t));
    335445                                               
    336                                                 heap_block_head_t *prev_head =
    337                                                     (heap_block_head_t *) (((void *) cur) - prev_foot->size);
     446                                                heap_block_head_t *prev_head = (heap_block_head_t *)
     447                                                    ((void *) cur - prev_foot->size);
    338448                                               
    339449                                                block_check(prev_head);
     
    342452                                                heap_block_head_t *next_head = ((void *) cur) + excess;
    343453                                               
    344                                                 if ((!prev_head->free) && (excess >= STRUCT_OVERHEAD)) {
    345                                                         /* The previous block is not free and there is enough
    346                                                            space to fill in a new free block between the previous
    347                                                            and current block */
    348                                                         block_init(cur, excess, true);
     454                                                if ((!prev_head->free) &&
     455                                                    (excess >= STRUCT_OVERHEAD)) {
     456                                                        /*
     457                                                         * The previous block is not free and there
     458                                                         * is enough free space left to fill in
     459                                                         * a new free block between the previous
     460                                                         * and current block.
     461                                                         */
     462                                                        block_init(cur, excess, true, area);
    349463                                                } else {
    350                                                         /* The previous block is free (thus there is no need to
    351                                                            induce additional fragmentation to the heap) or the
    352                                                            excess is small, thus just enlarge the previous block */
    353                                                         block_init(prev_head, prev_head->size + excess, prev_head->free);
     464                                                        /*
     465                                                         * The previous block is free (thus there
     466                                                         * is no need to induce additional
     467                                                         * fragmentation to the heap) or the
     468                                                         * excess is small. Therefore just enlarge
     469                                                         * the previous block.
     470                                                         */
     471                                                        block_init(prev_head, prev_head->size + excess,
     472                                                            prev_head->free, area);
    354473                                                }
    355474                                               
    356                                                 block_init(next_head, reduced_size, true);
     475                                                block_init(next_head, reduced_size, true, area);
    357476                                                split_mark(next_head, real_size);
    358                                                 result = aligned;
    359                                                 cur = next_head;
     477                                               
     478                                                next = next_head;
     479                                                return aligned;
    360480                                        } else {
    361                                                 /* The current block is the first block on the heap.
    362                                                    We have to make sure that the alignment excess
    363                                                    is large enough to fit a new free block just
    364                                                    before the current block */
     481                                                /*
     482                                                 * The current block is the first block
     483                                                 * in the heap area. We have to make sure
     484                                                 * that the alignment excess is large enough
     485                                                 * to fit a new free block just before the
     486                                                 * current block.
     487                                                 */
    365488                                                while (excess < STRUCT_OVERHEAD) {
    366489                                                        aligned += falign;
     
    371494                                                if (cur->size >= real_size + excess) {
    372495                                                        size_t reduced_size = cur->size - excess;
    373                                                         cur = (heap_block_head_t *) (heap_start + excess);
     496                                                        cur = (heap_block_head_t *)
     497                                                            (AREA_FIRST_BLOCK(area) + excess);
    374498                                                       
    375                                                         block_init(heap_start, excess, true);
    376                                                         block_init(cur, reduced_size, true);
     499                                                        block_init((void *) AREA_FIRST_BLOCK(area), excess,
     500                                                            true, area);
     501                                                        block_init(cur, reduced_size, true, area);
    377502                                                        split_mark(cur, real_size);
    378                                                         result = aligned;
     503                                                       
     504                                                        next = cur;
     505                                                        return aligned;
    379506                                                }
    380507                                        }
     
    382509                        }
    383510                }
    384                
    385                 /* Advance to the next block. */
    386                 cur = (heap_block_head_t *) (((void *) cur) + cur->size);
    387         }
    388        
    389         if ((result == NULL) && (!grown)) {
    390                 if (grow_heap(real_size)) {
    391                         grown = true;
     511        }
     512       
     513        return NULL;
     514}
     515
     516/** Allocate a memory block
     517 *
     518 * Should be called only inside the critical section.
     519 *
     520 * @param size  The size of the block to allocate.
     521 * @param align Memory address alignment.
     522 *
     523 * @return Address of the allocated block or NULL on not enough memory.
     524 *
     525 */
     526static void *malloc_internal(const size_t size, const size_t align)
     527{
     528        assert(first_heap_area != NULL);
     529       
     530        if (align == 0)
     531                return NULL;
     532       
     533        size_t falign = lcm(align, BASE_ALIGN);
     534        size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
     535       
     536        bool retry = false;
     537        heap_block_head_t *split;
     538       
     539loop:
     540       
     541        /* Try the next fit approach */
     542        split = next;
     543       
     544        if (split != NULL) {
     545                void *addr = malloc_area(split->area, split, NULL, real_size,
     546                    falign);
     547               
     548                if (addr != NULL)
     549                        return addr;
     550        }
     551       
     552        /* Search the entire heap */
     553        heap_area_t *area;
     554        for (area = first_heap_area; area != NULL; area = area->next) {
     555                heap_block_head_t *first = (heap_block_head_t *)
     556                    AREA_FIRST_BLOCK(area);
     557               
     558                void *addr = malloc_area(area, first, split, real_size,
     559                    falign);
     560               
     561                if (addr != NULL)
     562                        return addr;
     563        }
     564       
     565        if (!retry) {
     566                /* Try to grow the heap space */
     567                if (heap_grow(real_size)) {
     568                        retry = true;
    392569                        goto loop;
    393570                }
    394571        }
    395572       
    396         return result;
     573        return NULL;
    397574}
    398575
     
    473650            (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
    474651       
    475         assert((void *) head >= heap_start);
    476         assert((void *) head < heap_end);
    477        
    478652        block_check(head);
    479653        assert(!head->free);
     654       
     655        heap_area_t *area = head->area;
     656       
     657        area_check(area);
     658        assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
     659        assert((void *) head < area->end);
    480660       
    481661        void *ptr = NULL;
     
    487667                /* Shrink */
    488668                if (orig_size - real_size >= STRUCT_OVERHEAD) {
    489                         /* Split the original block to a full block
    490                            and a trailing free block */
    491                         block_init((void *) head, real_size, false);
     669                        /*
     670                         * Split the original block to a full block
     671                         * and a trailing free block.
     672                         */
     673                        block_init((void *) head, real_size, false, area);
    492674                        block_init((void *) head + real_size,
    493                             orig_size - real_size, true);
    494                         shrink_heap();
     675                            orig_size - real_size, true, area);
     676                        heap_shrink();
    495677                }
    496678               
    497679                ptr = ((void *) head) + sizeof(heap_block_head_t);
    498680        } else {
    499                 /* Look at the next block. If it is free and the size is
    500                    sufficient then merge the two. Otherwise just allocate
    501                    a new block, copy the original data into it and
    502                    free the original block. */
     681                /*
     682                 * Look at the next block. If it is free and the size is
     683                 * sufficient then merge the two. Otherwise just allocate
     684                 * a new block, copy the original data into it and
     685                 * free the original block.
     686                 */
    503687                heap_block_head_t *next_head =
    504688                    (heap_block_head_t *) (((void *) head) + head->size);
    505689               
    506                 if (((void *) next_head < heap_end) &&
     690                if (((void *) next_head < area->end) &&
    507691                    (head->size + next_head->size >= real_size) &&
    508692                    (next_head->free)) {
    509693                        block_check(next_head);
    510                         block_init(head, head->size + next_head->size, false);
     694                        block_init(head, head->size + next_head->size, false, area);
    511695                        split_mark(head, real_size);
    512696                       
    513697                        ptr = ((void *) head) + sizeof(heap_block_head_t);
     698                        next = NULL;
    514699                } else
    515700                        reloc = true;
     
    542727            = (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
    543728       
    544         assert((void *) head >= heap_start);
    545         assert((void *) head < heap_end);
    546        
    547729        block_check(head);
    548730        assert(!head->free);
     731       
     732        heap_area_t *area = head->area;
     733       
     734        area_check(area);
     735        assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
     736        assert((void *) head < area->end);
    549737       
    550738        /* Mark the block itself as free. */
     
    555743            = (heap_block_head_t *) (((void *) head) + head->size);
    556744       
    557         if ((void *) next_head < heap_end) {
     745        if ((void *) next_head < area->end) {
    558746                block_check(next_head);
    559747                if (next_head->free)
    560                         block_init(head, head->size + next_head->size, true);
     748                        block_init(head, head->size + next_head->size, true, area);
    561749        }
    562750       
    563751        /* Look at the previous block. If it is free, merge the two. */
    564         if ((void *) head > heap_start) {
     752        if ((void *) head > (void *) AREA_FIRST_BLOCK(area)) {
    565753                heap_block_foot_t *prev_foot =
    566754                    (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
     
    572760               
    573761                if (prev_head->free)
    574                         block_init(prev_head, prev_head->size + head->size, true);
    575         }
    576        
    577         shrink_heap();
     762                        block_init(prev_head, prev_head->size + head->size, true,
     763                            area);
     764        }
     765       
     766        heap_shrink();
    578767       
    579768        futex_up(&malloc_futex);
  • uspace/lib/c/generic/private/libc.h

    r5716e9a r76b5a95c  
    3636#define LIBC_PRIVATE_LIBC_H_
    3737
     38extern void __entry(void);
     39extern void __main(void *) __attribute__((noreturn));
    3840extern int main(int, char *[]);
    39 extern void __main(void *) __attribute__((noreturn));
    4041
    4142#endif
  • uspace/lib/c/include/as.h

    r5716e9a r76b5a95c  
    4141#include <libarch/config.h>
    4242
     43static inline size_t SIZE2PAGES(size_t size)
     44{
     45        if (size == 0)
     46                return 0;
     47       
     48        return (size_t) ((size - 1) >> PAGE_WIDTH) + 1;
     49}
     50
     51static inline size_t PAGES2SIZE(size_t pages)
     52{
     53        return (size_t) (pages << PAGE_WIDTH);
     54}
     55
    4356extern void *as_area_create(void *address, size_t size, int flags);
    4457extern int as_area_resize(void *address, size_t size, int flags);
  • uspace/lib/c/include/devman.h

    r5716e9a r76b5a95c  
    4545
    4646extern int devman_driver_register(const char *, async_client_conn_t);
    47 extern int devman_child_device_register(const char *, match_id_list_t *,
     47extern int devman_add_function(const char *, fun_type_t, match_id_list_t *,
    4848    devman_handle_t, devman_handle_t *);
    4949
  • uspace/lib/c/include/ipc/devman.h

    r5716e9a r76b5a95c  
    4242
    4343typedef sysarg_t devman_handle_t;
     44
     45typedef enum {
     46        /** Invalid value for debugging purposes */
     47        fun_invalid = 0,
     48        /** Function to which child devices attach */
     49        fun_inner,
     50        /** Fuction exported to external clients (leaf function) */
     51        fun_exposed
     52} fun_type_t;
    4453
    4554/** Ids of device models used for device-to-driver matching.
     
    127136typedef enum {
    128137        DEVMAN_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
    129         DEVMAN_ADD_CHILD_DEVICE,
     138        DEVMAN_ADD_FUNCTION,
    130139        DEVMAN_ADD_MATCH_ID,
    131140        DEVMAN_ADD_DEVICE_TO_CLASS
  • uspace/lib/c/include/malloc.h

    r5716e9a r76b5a95c  
    3838#include <sys/types.h>
    3939
    40 extern uintptr_t get_max_heap_addr(void);
    41 
    4240extern void *malloc(const size_t size)
    4341    __attribute__((malloc));
  • uspace/lib/c/include/unistd.h

    r5716e9a r76b5a95c  
    4444#endif
    4545
    46 #define getpagesize()  (PAGE_SIZE)
    47 
    4846#ifndef SEEK_SET
    4947        #define SEEK_SET  0
     
    5755        #define SEEK_END  2
    5856#endif
     57
     58#define getpagesize()  (PAGE_SIZE)
    5959
    6060extern int dup2(int oldfd, int newfd);
  • uspace/lib/drv/generic/driver.c

    r5716e9a r76b5a95c  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4950#include <errno.h>
    5051#include <inttypes.h>
     52#include <devman.h>
    5153
    5254#include <ipc/driver.h>
    5355
    5456#include "dev_iface.h"
    55 #include "driver.h"
     57#include "ddf/driver.h"
     58#include "ddf/interrupt.h"
    5659
    5760/** Driver structure */
     
    5962
    6063/** Devices */
    61 LIST_INITIALIZE(devices);
    62 FIBRIL_MUTEX_INITIALIZE(devices_mutex);
     64LIST_INITIALIZE(functions);
     65FIBRIL_MUTEX_INITIALIZE(functions_mutex);
    6366
    6467/** Interrupts */
     
    7679};
    7780
     81static ddf_dev_t *create_device(void);
     82static void delete_device(ddf_dev_t *);
     83static remote_handler_t *function_get_default_handler(ddf_fun_t *);
     84static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t);
    7885
    7986static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
     
    150157
    151158interrupt_context_t *
    152 find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq)
     159find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
    153160{
    154161        fibril_mutex_lock(&list->mutex);
     
    172179
    173180int
    174 register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler,
     181register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,
    175182    irq_code_t *pseudocode)
    176183{
     
    195202}
    196203
    197 int unregister_interrupt_handler(device_t *dev, int irq)
     204int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
    198205{
    199206        interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,
     
    209216}
    210217
    211 static void add_to_devices_list(device_t *dev)
    212 {
    213         fibril_mutex_lock(&devices_mutex);
    214         list_append(&dev->link, &devices);
    215         fibril_mutex_unlock(&devices_mutex);
    216 }
    217 
    218 static void remove_from_devices_list(device_t *dev)
    219 {
    220         fibril_mutex_lock(&devices_mutex);
    221         list_remove(&dev->link);
    222         fibril_mutex_unlock(&devices_mutex);
    223 }
    224 
    225 static device_t *driver_get_device(link_t *devices, devman_handle_t handle)
    226 {
    227         device_t *dev = NULL;
    228        
    229         fibril_mutex_lock(&devices_mutex);
    230         link_t *link = devices->next;
    231        
    232         while (link != devices) {
    233                 dev = list_get_instance(link, device_t, link);
    234                 if (dev->handle == handle) {
    235                         fibril_mutex_unlock(&devices_mutex);
    236                         return dev;
     218static void add_to_functions_list(ddf_fun_t *fun)
     219{
     220        fibril_mutex_lock(&functions_mutex);
     221        list_append(&fun->link, &functions);
     222        fibril_mutex_unlock(&functions_mutex);
     223}
     224
     225static void remove_from_functions_list(ddf_fun_t *fun)
     226{
     227        fibril_mutex_lock(&functions_mutex);
     228        list_remove(&fun->link);
     229        fibril_mutex_unlock(&functions_mutex);
     230}
     231
     232static ddf_fun_t *driver_get_function(link_t *functions, devman_handle_t handle)
     233{
     234        ddf_fun_t *fun = NULL;
     235       
     236        fibril_mutex_lock(&functions_mutex);
     237        link_t *link = functions->next;
     238       
     239        while (link != functions) {
     240                fun = list_get_instance(link, ddf_fun_t, link);
     241                if (fun->handle == handle) {
     242                        fibril_mutex_unlock(&functions_mutex);
     243                        return fun;
    237244                }
     245               
    238246                link = link->next;
    239247        }
    240248       
    241         fibril_mutex_unlock(&devices_mutex);
     249        fibril_mutex_unlock(&functions_mutex);
    242250       
    243251        return NULL;
     
    250258       
    251259        devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
    252         devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
    253        
    254         device_t *dev = create_device();
     260        devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
     261       
     262        ddf_dev_t *dev = create_device();
    255263        dev->handle = dev_handle;
    256        
     264
    257265        async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);
    258266        dev->name = dev_name;
    259        
    260         add_to_devices_list(dev);
    261         dev->parent = driver_get_device(&devices, parent_dev_handle);
     267
     268        /*
     269         * Currently not used, parent fun handle is stored in context
     270         * of the connection to the parent device driver.
     271         */
     272        (void) parent_fun_handle;
    262273       
    263274        res = driver->driver_ops->add_device(dev);
     
    268279                printf("%s: failed to add a new device with handle = %" PRIun ".\n",
    269280                    driver->name, dev_handle);
    270                 remove_from_devices_list(dev);
    271281                delete_device(dev);
    272282        }
     
    311321         */
    312322        devman_handle_t handle = IPC_GET_ARG2(*icall);
    313         device_t *dev = driver_get_device(&devices, handle);
    314 
    315         if (dev == NULL) {
    316                 printf("%s: driver_connection_gen error - no device with handle"
     323        ddf_fun_t *fun = driver_get_function(&functions, handle);
     324
     325        if (fun == NULL) {
     326                printf("%s: driver_connection_gen error - no function with handle"
    317327                    " %" PRIun " was found.\n", driver->name, handle);
    318328                async_answer_0(iid, ENOENT);
     
    327337       
    328338        int ret = EOK;
    329         /* open the device */
    330         if (dev->ops != NULL && dev->ops->open != NULL)
    331                 ret = (*dev->ops->open)(dev);
     339        /* Open device function */
     340        if (fun->ops != NULL && fun->ops->open != NULL)
     341                ret = (*fun->ops->open)(fun);
    332342       
    333343        async_answer_0(iid, ret);
     
    344354                switch  (method) {
    345355                case IPC_M_PHONE_HUNGUP:
    346                         /* close the device */
    347                         if (dev->ops != NULL && dev->ops->close != NULL)
    348                                 (*dev->ops->close)(dev);
     356                        /* Close device function */
     357                        if (fun->ops != NULL && fun->ops->close != NULL)
     358                                (*fun->ops->close)(fun);
    349359                        async_answer_0(callid, EOK);
    350360                        return;
     
    356366                        if (!is_valid_iface_idx(iface_idx)) {
    357367                                remote_handler_t *default_handler =
    358                                     device_get_default_handler(dev);
     368                                    function_get_default_handler(fun);
    359369                                if (default_handler != NULL) {
    360                                         (*default_handler)(dev, callid, &call);
     370                                        (*default_handler)(fun, callid, &call);
    361371                                        break;
    362372                                }
     373                               
    363374                                /*
    364                                  * This is not device's interface and the
     375                                 * Function has no such interface and
    365376                                 * default handler is not provided.
    366377                                 */
     
    372383                        }
    373384                       
    374                         /* calling one of the device's interfaces */
     385                        /* calling one of the function's interfaces */
    375386                       
    376387                        /* Get the interface ops structure. */
    377                         void *ops = device_get_ops(dev, iface_idx);
     388                        void *ops = function_get_ops(fun, iface_idx);
    378389                        if (ops == NULL) {
    379390                                printf("%s: driver_connection_gen error - ",
    380391                                    driver->name);
    381                                 printf("device with handle %" PRIun " has no interface "
     392                                printf("Function with handle %" PRIun " has no interface "
    382393                                    "with id %d.\n", handle, iface_idx);
    383394                                async_answer_0(callid, ENOTSUP);
     
    408419                         * receive parameters from the remote client and it will
    409420                         * pass it to the corresponding local interface method
    410                          * associated with the device by its driver.
     421                         * associated with the function by its driver.
    411422                         */
    412                         (*iface_method_ptr)(dev, ops, callid, &call);
     423                        (*iface_method_ptr)(fun, ops, callid, &call);
    413424                        break;
    414425                }
     
    425436        driver_connection_gen(iid, icall, false);
    426437}
    427 
    428438
    429439/** Function for handling connections to device driver. */
     
    454464 * @return              The device structure.
    455465 */
    456 device_t *create_device(void)
    457 {
    458         device_t *dev = malloc(sizeof(device_t));
    459 
    460         if (dev != NULL) {
    461                 memset(dev, 0, sizeof(device_t));
    462                 init_match_ids(&dev->match_ids);
    463         }
    464 
     466static ddf_dev_t *create_device(void)
     467{
     468        ddf_dev_t *dev;
     469
     470        dev = malloc(sizeof(ddf_dev_t));
     471        if (dev == NULL)
     472                return NULL;
     473
     474        memset(dev, 0, sizeof(ddf_dev_t));
    465475        return dev;
    466476}
    467477
     478/** Create new function structure.
     479 *
     480 * @return              The device structure.
     481 */
     482static ddf_fun_t *create_function(void)
     483{
     484        ddf_fun_t *fun;
     485
     486        fun = calloc(1, sizeof(ddf_fun_t));
     487        if (fun == NULL)
     488                return NULL;
     489
     490        init_match_ids(&fun->match_ids);
     491        link_initialize(&fun->link);
     492
     493        return fun;
     494}
     495
    468496/** Delete device structure.
    469497 *
    470498 * @param dev           The device structure.
    471499 */
    472 void delete_device(device_t *dev)
    473 {
    474         clean_match_ids(&dev->match_ids);
    475         if (dev->name != NULL)
    476                 free(dev->name);
     500static void delete_device(ddf_dev_t *dev)
     501{
    477502        free(dev);
    478503}
    479504
    480 void *device_get_ops(device_t *dev, dev_inferface_idx_t idx)
     505/** Delete device structure.
     506 *
     507 * @param dev           The device structure.
     508 */
     509static void delete_function(ddf_fun_t *fun)
     510{
     511        clean_match_ids(&fun->match_ids);
     512        if (fun->name != NULL)
     513                free(fun->name);
     514        free(fun);
     515}
     516
     517/** Create a DDF function node.
     518 *
     519 * Create a DDF function (in memory). Both child devices and external clients
     520 * communicate with a device via its functions.
     521 *
     522 * The created function node is fully formed, but only exists in the memory
     523 * of the client task. In order to be visible to the system, the function
     524 * must be bound using ddf_fun_bind().
     525 *
     526 * This function should only fail if there is not enough free memory.
     527 * Specifically, this function succeeds even if @a dev already has
     528 * a (bound) function with the same name.
     529 *
     530 * Type: A function of type fun_inner indicates that DDF should attempt
     531 * to attach child devices to the function. fun_exposed means that
     532 * the function should be exported to external clients (applications).
     533 *
     534 * @param dev           Device to which we are adding function
     535 * @param ftype         Type of function (fun_inner or fun_exposed)
     536 * @param name          Name of function
     537 *
     538 * @return              New function or @c NULL if memory is not available
     539 */
     540ddf_fun_t *ddf_fun_create(ddf_dev_t *dev, fun_type_t ftype, const char *name)
     541{
     542        ddf_fun_t *fun;
     543
     544        fun = create_function();
     545        if (fun == NULL)
     546                return NULL;
     547
     548        fun->bound = false;
     549        fun->dev = dev;
     550        fun->ftype = ftype;
     551
     552        fun->name = str_dup(name);
     553        if (fun->name == NULL) {
     554                delete_function(fun);
     555                return NULL;
     556        }
     557
     558        return fun;
     559}
     560
     561/** Destroy DDF function node.
     562 *
     563 * Destroy a function previously created with ddf_fun_create(). The function
     564 * must not be bound.
     565 *
     566 * @param fun           Function to destroy
     567 */
     568void ddf_fun_destroy(ddf_fun_t *fun)
     569{
     570        assert(fun->bound == false);
     571        delete_function(fun);
     572}
     573
     574static void *function_get_ops(ddf_fun_t *fun, dev_inferface_idx_t idx)
    481575{
    482576        assert(is_valid_iface_idx(idx));
    483         if (dev->ops == NULL)
     577        if (fun->ops == NULL)
    484578                return NULL;
    485         return dev->ops->interfaces[idx];
    486 }
    487 
    488 int child_device_register(device_t *child, device_t *parent)
    489 {
    490         assert(child->name != NULL);
     579        return fun->ops->interfaces[idx];
     580}
     581
     582/** Bind a function node.
     583 *
     584 * Bind the specified function to the system. This effectively makes
     585 * the function visible to the system (uploads it to the server).
     586 *
     587 * This function can fail for several reasons. Specifically,
     588 * it will fail if the device already has a bound function of
     589 * the same name.
     590 *
     591 * @param fun           Function to bind
     592 * @return              EOK on success or negative error code
     593 */
     594int ddf_fun_bind(ddf_fun_t *fun)
     595{
     596        assert(fun->name != NULL);
    491597       
    492598        int res;
    493599       
    494         add_to_devices_list(child);
    495         res = devman_child_device_register(child->name, &child->match_ids,
    496             parent->handle, &child->handle);
     600        add_to_functions_list(fun);
     601        res = devman_add_function(fun->name, fun->ftype, &fun->match_ids,
     602            fun->dev->handle, &fun->handle);
    497603        if (res != EOK) {
    498                 remove_from_devices_list(child);
     604                remove_from_functions_list(fun);
    499605                return res;
    500606        }
    501607       
     608        fun->bound = true;
    502609        return res;
    503610}
    504611
    505 /** Wrapper for child_device_register for devices with single match id.
    506  *
    507  * @param parent Parent device.
    508  * @param child_name Child device name.
    509  * @param child_match_id Child device match id.
    510  * @param child_match_score Child device match score.
    511  * @return Error code.
    512  */
    513 int child_device_register_wrapper(device_t *parent, const char *child_name,
    514     const char *child_match_id, int child_match_score)
    515 {
    516         device_t *child = NULL;
    517         match_id_t *match_id = NULL;
    518         int rc;
    519        
    520         child = create_device();
    521         if (child == NULL) {
    522                 rc = ENOMEM;
    523                 goto failure;
    524         }
    525        
    526         child->name = child_name;
     612/** Add single match ID to inner function.
     613 *
     614 * Construct and add a single match ID to the specified function.
     615 * Cannot be called when the function node is bound.
     616 *
     617 * @param fun                   Function
     618 * @param match_id_str          Match string
     619 * @param match_score           Match score
     620 * @return                      EOK on success, ENOMEM if out of memory.
     621 */
     622int ddf_fun_add_match_id(ddf_fun_t *fun, const char *match_id_str,
     623    int match_score)
     624{
     625        match_id_t *match_id;
     626       
     627        assert(fun->bound == false);
     628        assert(fun->ftype == fun_inner);
    527629       
    528630        match_id = create_match_id();
    529         if (match_id == NULL) {
    530                 rc = ENOMEM;
    531                 goto failure;
    532         }
    533        
    534         match_id->id = child_match_id;
    535         match_id->score = child_match_score;
    536         add_match_id(&child->match_ids, match_id);
    537        
    538         rc = child_device_register(child, parent);
    539         if (rc != EOK)
    540                 goto failure;
    541        
     631        if (match_id == NULL)
     632                return ENOMEM;
     633       
     634        match_id->id = match_id_str;
     635        match_id->score = 90;
     636       
     637        add_match_id(&fun->match_ids, match_id);
    542638        return EOK;
    543        
    544 failure:
    545         if (match_id != NULL) {
    546                 match_id->id = NULL;
    547                 delete_match_id(match_id);
    548         }
    549        
    550         if (child != NULL) {
    551                 child->name = NULL;
    552                 delete_device(child);
    553         }
    554        
    555         return rc;
    556639}
    557640
    558641/** Get default handler for client requests */
    559 remote_handler_t *device_get_default_handler(device_t *dev)
    560 {
    561         if (dev->ops == NULL)
     642static remote_handler_t *function_get_default_handler(ddf_fun_t *fun)
     643{
     644        if (fun->ops == NULL)
    562645                return NULL;
    563         return dev->ops->default_handler;
    564 }
    565 
    566 int add_device_to_class(device_t *dev, const char *class_name)
    567 {
    568         return devman_add_device_to_class(dev->handle, class_name);
    569 }
    570 
    571 int driver_main(driver_t *drv)
     646        return fun->ops->default_handler;
     647}
     648
     649/** Add exposed function to class.
     650 *
     651 * Must only be called when the function is bound.
     652 */
     653int ddf_fun_add_to_class(ddf_fun_t *fun, const char *class_name)
     654{
     655        assert(fun->bound == true);
     656        assert(fun->ftype == fun_exposed);
     657       
     658        return devman_add_device_to_class(fun->handle, class_name);
     659}
     660
     661int ddf_driver_main(driver_t *drv)
    572662{
    573663        /*
  • uspace/lib/drv/generic/remote_char_dev.c

    r5716e9a r76b5a95c  
    3737
    3838#include "ops/char_dev.h"
    39 #include "driver.h"
     39#include "ddf/driver.h"
    4040
    4141#define MAX_CHAR_RW_COUNT 256
    4242
    43 static void remote_char_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
    44 static void remote_char_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
     43static void remote_char_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     44static void remote_char_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    4545
    4646/** Remote character interface operations. */
     
    6767 * local interface to the remote client.
    6868 *
    69  * @param dev           The device from which the data are read.
     69 * @param fun           The function from which the data are read.
    7070 * @param ops           The local ops structure.
    7171 */
    7272static void
    73 remote_char_read(device_t *dev, void *ops, ipc_callid_t callid,
     73remote_char_read(ddf_fun_t *fun, void *ops, ipc_callid_t callid,
    7474    ipc_call_t *call)
    7575{
     
    9494       
    9595        char buf[MAX_CHAR_RW_COUNT];
    96         int ret = (*char_dev_ops->read)(dev, buf, len);
     96        int ret = (*char_dev_ops->read)(fun, buf, len);
    9797       
    9898        if (ret < 0) {
     
    114114 * local interface to the remote client.
    115115 *
    116  * @param dev           The device to which the data are written.
     116 * @param fun           The function to which the data are written.
    117117 * @param ops           The local ops structure.
    118118 */
    119119static void
    120 remote_char_write(device_t *dev, void *ops, ipc_callid_t callid,
     120remote_char_write(ddf_fun_t *fun, void *ops, ipc_callid_t callid,
    121121    ipc_call_t *call)
    122122{
     
    144144        async_data_write_finalize(cid, buf, len);
    145145       
    146         int ret = (*char_dev_ops->write)(dev, buf, len);
     146        int ret = (*char_dev_ops->write)(fun, buf, len);
    147147        if (ret < 0) {
    148148                /* Some error occured. */
  • uspace/lib/drv/generic/remote_hw_res.c

    r5716e9a r76b5a95c  
    3737
    3838#include "ops/hw_res.h"
    39 #include "driver.h"
     39#include "ddf/driver.h"
    4040
    41 static void remote_hw_res_get_resource_list(device_t *, void *, ipc_callid_t,
     41static void remote_hw_res_get_resource_list(ddf_fun_t *, void *, ipc_callid_t,
    4242    ipc_call_t *);
    43 static void remote_hw_res_enable_interrupt(device_t *, void *, ipc_callid_t,
     43static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
    4444    ipc_call_t *);
    4545
     
    5555};
    5656
    57 static void remote_hw_res_enable_interrupt(device_t *dev, void *ops,
     57static void remote_hw_res_enable_interrupt(ddf_fun_t *fun, void *ops,
    5858    ipc_callid_t callid, ipc_call_t *call)
    5959{
     
    6262        if (hw_res_ops->enable_interrupt == NULL)
    6363                async_answer_0(callid, ENOTSUP);
    64         else if (hw_res_ops->enable_interrupt(dev))
     64        else if (hw_res_ops->enable_interrupt(fun))
    6565                async_answer_0(callid, EOK);
    6666        else
     
    6868}
    6969
    70 static void remote_hw_res_get_resource_list(device_t *dev, void *ops,
     70static void remote_hw_res_get_resource_list(ddf_fun_t *fun, void *ops,
    7171    ipc_callid_t callid, ipc_call_t *call)
    7272{
     
    7878        }
    7979       
    80         hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(dev);
     80        hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(fun);
    8181        if (hw_resources == NULL){
    8282                async_answer_0(callid, ENOENT);
  • uspace/lib/drv/include/ddf/driver.h

    r5716e9a r76b5a95c  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3334 */
    3435
    35 #ifndef LIBDRV_DRIVER_H_
    36 #define LIBDRV_DRIVER_H_
     36#ifndef DDF_DRIVER_H_
     37#define DDF_DRIVER_H_
    3738
    38 #include <kernel/ddi/irq.h>
    39 #include <adt/list.h>
    40 #include <devman.h>
    4139#include <ipc/devman.h>
    4240#include <ipc/dev_iface.h>
    43 #include <assert.h>
    44 #include <ddi.h>
    45 #include <libarch/ddi.h>
    46 #include <fibril_synch.h>
    47 #include <malloc.h>
    4841
    49 #include "dev_iface.h"
     42#include "../dev_iface.h"
    5043
    51 struct device;
    52 typedef struct device device_t;
     44typedef struct ddf_dev ddf_dev_t;
     45typedef struct ddf_fun ddf_fun_t;
    5346
    5447/*
    55  * Device class
     48 * Device
    5649 */
    5750
    5851/** Devices operations */
    59 typedef struct device_ops {
     52typedef struct ddf_dev_ops {
    6053        /**
    6154         * Optional callback function called when a client is connecting to the
    6255         * device.
    6356         */
    64         int (*open)(device_t *);
     57        int (*open)(ddf_fun_t *);
    6558       
    6659        /**
     
    6861         * the device.
    6962         */
    70         void (*close)(device_t *);
     63        void (*close)(ddf_fun_t *);
    7164       
    7265        /** The table of standard interfaces implemented by the device. */
     
    7972         */
    8073        remote_handler_t *default_handler;
    81 } device_ops_t;
    82 
    83 
    84 /*
    85  * Device
    86  */
     74} ddf_dev_ops_t;
    8775
    8876/** Device structure */
    89 struct device {
     77struct ddf_dev {
    9078        /**
    9179         * Globally unique device identifier (assigned to the device by the
     
    10088        int parent_phone;
    10189       
    102         /** Parent device if handled by this driver, NULL otherwise */
    103         device_t *parent;
    10490        /** Device name */
    10591        const char *name;
    106         /** List of device ids for device-to-driver matching */
    107         match_id_list_t match_ids;
     92       
    10893        /** Driver-specific data associated with this device */
    10994        void *driver_data;
    110         /** The implementation of operations provided by this device */
    111         device_ops_t *ops;
    11295       
    11396        /** Link in the list of devices handled by the driver */
     97        link_t link;
     98};
     99
     100/** Function structure */
     101struct ddf_fun {
     102        /** True if bound to the device manager */
     103        bool bound;
     104        /** Function indentifier (asigned by device manager) */
     105        devman_handle_t handle;
     106       
     107        /** Device which this function belogs to */
     108        ddf_dev_t *dev;
     109       
     110        /** Function type */
     111        fun_type_t ftype;
     112        /** Function name */
     113        const char *name;
     114        /** List of device ids for driver matching */
     115        match_id_list_t match_ids;
     116        /** Driver-specific data associated with this function */
     117        void *driver_data;
     118        /** Implementation of operations provided by this function */
     119        ddf_dev_ops_t *ops;
     120       
     121        /** Link in the list of functions handled by the driver */
    114122        link_t link;
    115123};
     
    122130typedef struct driver_ops {
    123131        /** Callback method for passing a new device to the device driver */
    124         int (*add_device)(device_t *dev);
     132        int (*add_device)(ddf_dev_t *dev);
    125133        /* TODO: add other generic driver operations */
    126134} driver_ops_t;
     
    134142} driver_t;
    135143
    136 int driver_main(driver_t *);
     144extern int ddf_driver_main(driver_t *);
    137145
    138 /** Create new device structure.
    139  *
    140  * @return              The device structure.
    141  */
    142 extern device_t *create_device(void);
    143 extern void delete_device(device_t *);
    144 extern void *device_get_ops(device_t *, dev_inferface_idx_t);
     146extern ddf_fun_t *ddf_fun_create(ddf_dev_t *, fun_type_t, const char *);
     147extern void ddf_fun_destroy(ddf_fun_t *);
     148extern int ddf_fun_bind(ddf_fun_t *);
     149extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
    145150
    146 extern int child_device_register(device_t *, device_t *);
    147 extern int child_device_register_wrapper(device_t *, const char *, const char *,
    148     int);
    149 
    150 /*
    151  * Interrupts
    152  */
    153 
    154 typedef void interrupt_handler_t(device_t *, ipc_callid_t, ipc_call_t *);
    155 
    156 typedef struct interrupt_context {
    157         int id;
    158         device_t *dev;
    159         int irq;
    160         interrupt_handler_t *handler;
    161         link_t link;
    162 } interrupt_context_t;
    163 
    164 typedef struct interrupt_context_list {
    165         int curr_id;
    166         link_t contexts;
    167         fibril_mutex_t mutex;
    168 } interrupt_context_list_t;
    169 
    170 extern interrupt_context_t *create_interrupt_context(void);
    171 extern void delete_interrupt_context(interrupt_context_t *);
    172 extern void init_interrupt_context_list(interrupt_context_list_t *);
    173 extern void add_interrupt_context(interrupt_context_list_t *,
    174     interrupt_context_t *);
    175 extern void remove_interrupt_context(interrupt_context_list_t *,
    176     interrupt_context_t *);
    177 extern interrupt_context_t *find_interrupt_context_by_id(
    178     interrupt_context_list_t *, int);
    179 extern interrupt_context_t *find_interrupt_context(
    180     interrupt_context_list_t *, device_t *, int);
    181 
    182 extern int register_interrupt_handler(device_t *, int, interrupt_handler_t *,
    183     irq_code_t *);
    184 extern int unregister_interrupt_handler(device_t *, int);
    185 
    186 extern remote_handler_t *device_get_default_handler(device_t *);
    187 extern int add_device_to_class(device_t *, const char *);
     151extern int ddf_fun_add_to_class(ddf_fun_t *, const char *);
    188152
    189153#endif
  • uspace/lib/drv/include/dev_iface.h

    r5716e9a r76b5a95c  
    4343 */
    4444
    45 struct device;
     45struct ddf_fun;
    4646
    4747/*
     
    4949 * devices driver.
    5050 */
    51 typedef void remote_iface_func_t(struct device *, void *, ipc_callid_t,
     51typedef void remote_iface_func_t(struct ddf_fun *, void *, ipc_callid_t,
    5252    ipc_call_t *);
    5353typedef remote_iface_func_t *remote_iface_func_ptr_t;
    54 typedef void remote_handler_t(struct device *, ipc_callid_t, ipc_call_t *);
     54typedef void remote_handler_t(struct ddf_fun *, ipc_callid_t, ipc_call_t *);
    5555
    5656typedef struct {
  • uspace/lib/drv/include/ops/char_dev.h

    r5716e9a r76b5a95c  
    3636#define LIBDRV_OPS_CHAR_DEV_H_
    3737
    38 #include "../driver.h"
     38#include "../ddf/driver.h"
    3939
    4040typedef struct {
    41         int (*read)(device_t *, char *, size_t);
    42         int (*write)(device_t *, char *, size_t);
     41        int (*read)(ddf_fun_t *, char *, size_t);
     42        int (*write)(ddf_fun_t *, char *, size_t);
    4343} char_dev_ops_t;
    4444
  • uspace/lib/drv/include/ops/hw_res.h

    r5716e9a r76b5a95c  
    3939#include <sys/types.h>
    4040
    41 #include "../driver.h"
     41#include "../ddf/driver.h"
    4242
    4343typedef struct {
    44          hw_resource_list_t *(*get_resource_list)(device_t *);
    45          bool (*enable_interrupt)(device_t *);
     44         hw_resource_list_t *(*get_resource_list)(ddf_fun_t *);
     45         bool (*enable_interrupt)(ddf_fun_t *);
    4646} hw_res_ops_t;
    4747
Note: See TracChangeset for help on using the changeset viewer.