Changeset 8b1e15ac in mainline


Ignore:
Timestamp:
2011-02-11T22:26:36Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
68414f4a
Parents:
1b367b4
Message:

Finish splitting device node: devman client in C library, drv library. Update device drivers accordingly.

Location:
uspace
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/tester/hw/serial/serial1.c

    r1b367b4 r8b1e15ac  
    7474       
    7575        devman_handle_t handle;
    76         res = devman_device_get_handle("/hw/pci0/00:01.0/com1", &handle,
     76        res = devman_device_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
    7777            IPC_FLAG_BLOCKING);
    7878        if (res != EOK)
  • uspace/drv/isa/isa.c

    r1b367b4 r8b1e15ac  
    5858
    5959#define NAME "isa"
    60 #define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev"
     60#define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
    6161
    6262#define ISA_MAX_HW_RES 4
    6363
    64 typedef struct isa_child_data {
     64typedef struct isa_fun_data {
    6565        hw_resource_list_t hw_resources;
    66 } isa_child_data_t;
    67 
    68 static hw_resource_list_t *isa_get_child_resources(device_t *dev)
    69 {
    70         isa_child_data_t *dev_data;
    71 
    72         dev_data = (isa_child_data_t *)dev->driver_data;
    73         if (dev_data == NULL)
     66} isa_fun_data_t;
     67
     68static hw_resource_list_t *isa_get_fun_resources(function_t *fun)
     69{
     70        isa_fun_data_t *fun_data;
     71
     72        fun_data = (isa_fun_data_t *)fun->driver_data;
     73        if (fun_data == NULL)
    7474                return NULL;
    7575
    76         return &dev_data->hw_resources;
    77 }
    78 
    79 static bool isa_enable_child_interrupt(device_t *dev)
     76        return &fun_data->hw_resources;
     77}
     78
     79static bool isa_enable_fun_interrupt(function_t *fun)
    8080{
    8181        // TODO
     
    8484}
    8585
    86 static hw_res_ops_t isa_child_hw_res_ops = {
    87         &isa_get_child_resources,
    88         &isa_enable_child_interrupt
     86static hw_res_ops_t isa_fun_hw_res_ops = {
     87        &isa_get_fun_resources,
     88        &isa_enable_fun_interrupt
    8989};
    9090
    91 static device_ops_t isa_child_dev_ops;
     91static device_ops_t isa_fun_dev_ops;
    9292
    9393static int isa_add_device(device_t *dev);
     
    105105
    106106
    107 static isa_child_data_t *create_isa_child_data()
    108 {
    109         isa_child_data_t *data;
    110 
    111         data = (isa_child_data_t *) malloc(sizeof(isa_child_data_t));
     107static isa_fun_data_t *create_isa_fun_data()
     108{
     109        isa_fun_data_t *data;
     110
     111        data = (isa_fun_data_t *) malloc(sizeof(isa_fun_data_t));
    112112        if (data != NULL)
    113                 memset(data, 0, sizeof(isa_child_data_t));
     113                memset(data, 0, sizeof(isa_fun_data_t));
    114114
    115115        return data;
    116116}
    117117
    118 static device_t *create_isa_child_dev()
    119 {
    120         device_t *dev = create_device();
    121         if (dev == NULL)
     118static function_t *create_isa_fun()
     119{
     120        function_t *fun = create_function();
     121        if (fun == NULL)
    122122                return NULL;
    123123
    124         isa_child_data_t *data = create_isa_child_data();
     124        isa_fun_data_t *data = create_isa_fun_data();
    125125        if (data == NULL) {
    126                 delete_device(dev);
     126                delete_function(fun);
    127127                return NULL;
    128128        }
    129129
    130         dev->driver_data = data;
    131         return dev;
    132 }
    133 
    134 static char *read_dev_conf(const char *conf_path)
     130        fun->driver_data = data;
     131        return fun;
     132}
     133
     134static char *read_fun_conf(const char *conf_path)
    135135{
    136136        bool suc = false;
     
    151151        lseek(fd, 0, SEEK_SET);
    152152        if (len == 0) {
    153                 printf(NAME ": read_dev_conf error: configuration file '%s' "
     153                printf(NAME ": read_fun_conf error: configuration file '%s' "
    154154                    "is empty.\n", conf_path);
    155155                goto cleanup;
     
    158158        buf = malloc(len + 1);
    159159        if (buf == NULL) {
    160                 printf(NAME ": read_dev_conf error: memory allocation failed.\n");
     160                printf(NAME ": read_fun_conf error: memory allocation failed.\n");
    161161                goto cleanup;
    162162        }
    163163
    164164        if (0 >= read(fd, buf, len)) {
    165                 printf(NAME ": read_dev_conf error: unable to read file '%s'.\n",
     165                printf(NAME ": read_fun_conf error: unable to read file '%s'.\n",
    166166                    conf_path);
    167167                goto cleanup;
     
    249249}
    250250
    251 static void isa_child_set_irq(device_t *dev, int irq)
    252 {
    253         isa_child_data_t *data = (isa_child_data_t *)dev->driver_data;
     251static void isa_fun_set_irq(function_t *fun, int irq)
     252{
     253        isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data;
    254254
    255255        size_t count = data->hw_resources.count;
     
    262262                data->hw_resources.count++;
    263263
    264                 printf(NAME ": added irq 0x%x to device %s\n", irq, dev->name);
    265         }
    266 }
    267 
    268 static void isa_child_set_io_range(device_t *dev, size_t addr, size_t len)
    269 {
    270         isa_child_data_t *data = (isa_child_data_t *)dev->driver_data;
     264                printf(NAME ": added irq 0x%x to function %s\n", irq, fun->name);
     265        }
     266}
     267
     268static void isa_fun_set_io_range(function_t *fun, size_t addr, size_t len)
     269{
     270        isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data;
    271271
    272272        size_t count = data->hw_resources.count;
     
    282282
    283283                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
    284                     "device %s\n", (unsigned int) addr, (unsigned int) len,
    285                     dev->name);
    286         }
    287 }
    288 
    289 static void get_dev_irq(device_t *dev, char *val)
     284                    "function %s\n", (unsigned int) addr, (unsigned int) len,
     285                    fun->name);
     286        }
     287}
     288
     289static void get_dev_irq(function_t *fun, char *val)
    290290{
    291291        int irq = 0;
    292292        char *end = NULL;
    293293
    294         val = skip_spaces(val); 
     294        val = skip_spaces(val);
    295295        irq = (int)strtol(val, &end, 0x10);
    296296
    297297        if (val != end)
    298                 isa_child_set_irq(dev, irq);
    299 }
    300 
    301 static void get_dev_io_range(device_t *dev, char *val)
     298                isa_fun_set_irq(fun, irq);
     299}
     300
     301static void get_dev_io_range(function_t *fun, char *val)
    302302{
    303303        size_t addr, len;
    304304        char *end = NULL;
    305305
    306         val = skip_spaces(val); 
     306        val = skip_spaces(val);
    307307        addr = strtol(val, &end, 0x10);
    308308
     
    310310                return;
    311311
    312         val = skip_spaces(end); 
     312        val = skip_spaces(end);
    313313        len = strtol(val, &end, 0x10);
    314314
     
    316316                return;
    317317
    318         isa_child_set_io_range(dev, addr, len);
     318        isa_fun_set_io_range(fun, addr, len);
    319319}
    320320
     
    331331}
    332332
    333 static void get_dev_match_id(device_t *dev, char *val)
     333static void get_fun_match_id(function_t *fun, char *val)
    334334{
    335335        char *id = NULL;
     
    342342        if (val == end) {
    343343                printf(NAME " : error - could not read match score for "
    344                     "device %s.\n", dev->name);
     344                    "function %s.\n", fun->name);
    345345                return;
    346346        }
     
    348348        match_id_t *match_id = create_match_id();
    349349        if (match_id == NULL) {
    350                 printf(NAME " : failed to allocate match id for device %s.\n",
    351                     dev->name);
     350                printf(NAME " : failed to allocate match id for function %s.\n",
     351                    fun->name);
    352352                return;
    353353        }
     
    357357        if (id == NULL) {
    358358                printf(NAME " : error - could not read match id for "
    359                     "device %s.\n", dev->name);
     359                    "function %s.\n", fun->name);
    360360                delete_match_id(match_id);
    361361                return;
     
    365365        match_id->score = score;
    366366
    367         printf(NAME ": adding match id '%s' with score %d to device %s\n", id,
    368             score, dev->name);
    369         add_match_id(&dev->match_ids, match_id);
    370 }
    371 
    372 static bool read_dev_prop(device_t *dev, char *line, const char *prop,
    373     void (*read_fn)(device_t *, char *))
     367        printf(NAME ": adding match id '%s' with score %d to function %s\n", id,
     368            score, fun->name);
     369        add_match_id(&fun->match_ids, match_id);
     370}
     371
     372static bool read_fun_prop(function_t *fun, char *line, const char *prop,
     373    void (*read_fn)(function_t *, char *))
    374374{
    375375        size_t proplen = str_size(prop);
     
    378378                line += proplen;
    379379                line = skip_spaces(line);
    380                 (*read_fn)(dev, line);
     380                (*read_fn)(fun, line);
    381381
    382382                return true;
     
    386386}
    387387
    388 static void get_dev_prop(device_t *dev, char *line)
     388static void get_fun_prop(function_t *fun, char *line)
    389389{
    390390        /* Skip leading spaces. */
    391391        line = skip_spaces(line);
    392392
    393         if (!read_dev_prop(dev, line, "io_range", &get_dev_io_range) &&
    394             !read_dev_prop(dev, line, "irq", &get_dev_irq) &&
    395             !read_dev_prop(dev, line, "match", &get_dev_match_id))
     393        if (!read_fun_prop(fun, line, "io_range", &get_dev_io_range) &&
     394            !read_fun_prop(fun, line, "irq", &get_dev_irq) &&
     395            !read_fun_prop(fun, line, "match", &get_fun_match_id))
    396396        {
    397397            printf(NAME " error undefined device property at line '%s'\n",
     
    400400}
    401401
    402 static void child_alloc_hw_res(device_t *dev)
    403 {
    404         isa_child_data_t *data = (isa_child_data_t *)dev->driver_data;
     402static void child_alloc_hw_res(function_t *fun)
     403{
     404        isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data;
    405405        data->hw_resources.resources =
    406406            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    407407}
    408408
    409 static char *read_isa_dev_info(char *dev_conf, device_t *parent)
     409static char *read_isa_fun_info(char *fun_conf, device_t *dev)
    410410{
    411411        char *line;
    412         char *dev_name = NULL;
     412        char *fun_name = NULL;
    413413
    414414        /* Skip empty lines. */
    415415        while (true) {
    416                 line = str_get_line(dev_conf, &dev_conf);
     416                line = str_get_line(fun_conf, &fun_conf);
    417417
    418418                if (line == NULL) {
     
    426426
    427427        /* Get device name. */
    428         dev_name = get_device_name(line);
    429         if (dev_name == NULL)
     428        fun_name = get_device_name(line);
     429        if (fun_name == NULL)
    430430                return NULL;
    431431
    432         device_t *dev = create_isa_child_dev();
    433         if (dev == NULL) {
    434                 free(dev_name);
     432        function_t *fun = create_isa_fun();
     433        if (fun == NULL) {
     434                free(fun_name);
    435435                return NULL;
    436436        }
    437437
    438         dev->name = dev_name;
     438        fun->name = fun_name;
     439        fun->ftype = fun_inner;
    439440
    440441        /* Allocate buffer for the list of hardware resources of the device. */
    441         child_alloc_hw_res(dev);
     442        child_alloc_hw_res(fun);
    442443
    443444        /* Get properties of the device (match ids, irq and io range). */
    444445        while (true) {
    445                 line = str_get_line(dev_conf, &dev_conf);
     446                line = str_get_line(fun_conf, &fun_conf);
    446447
    447448                if (line_empty(line)) {
     
    454455                 * and store it in the device structure.
    455456                 */
    456                 get_dev_prop(dev, line);
    457 
    458                 //printf(NAME ": next line ='%s'\n", dev_conf);
     457                get_fun_prop(fun, line);
     458
     459                //printf(NAME ": next line ='%s'\n", fun_conf);
    459460                //printf(NAME ": current line ='%s'\n", line);
    460461        }
    461462
    462463        /* Set device operations to the device. */
    463         dev->ops = &isa_child_dev_ops;
    464 
    465         printf(NAME ": child_device_register(dev, parent); device is %s.\n",
    466             dev->name);
    467         child_device_register(dev, parent);
    468 
    469         return dev_conf;
    470 }
    471 
    472 static void parse_dev_conf(char *conf, device_t *parent)
     464        fun->ops = &isa_fun_dev_ops;
     465
     466        printf(NAME ": register_function(fun, dev); function is %s.\n",
     467            fun->name);
     468        register_function(fun, dev);
     469
     470        return fun_conf;
     471}
     472
     473static void parse_fun_conf(char *conf, device_t *dev)
    473474{
    474475        while (conf != NULL && *conf != '\0') {
    475                 conf = read_isa_dev_info(conf, parent);
    476         }
    477 }
    478 
    479 static void add_legacy_children(device_t *parent)
    480 {
    481         char *dev_conf;
    482 
    483         dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH);
    484         if (dev_conf != NULL) {
    485                 parse_dev_conf(dev_conf, parent);
    486                 free(dev_conf);
     476                conf = read_isa_fun_info(conf, dev);
     477        }
     478}
     479
     480static void add_legacy_children(device_t *dev)
     481{
     482        char *fun_conf;
     483
     484        fun_conf = read_fun_conf(CHILD_FUN_CONF_PATH);
     485        if (fun_conf != NULL) {
     486                parse_fun_conf(fun_conf, dev);
     487                free(fun_conf);
    487488        }
    488489}
     
    492493        printf(NAME ": isa_add_device, device handle = %d\n",
    493494            (int) dev->handle);
     495
     496        /* Make the bus device more visible. Does not do anything. */
     497        printf(NAME ": adding a 'ctl' function\n");
     498
     499        function_t *ctl = create_function();
     500        ctl->ftype = fun_exposed;
     501        ctl->name = "ctl";
     502        register_function(ctl, dev);
    494503
    495504        /* Add child devices. */
     
    502511static void isa_init()
    503512{
    504         isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_hw_res_ops;
     513        isa_fun_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
    505514}
    506515
  • uspace/drv/ns8250/ns8250.c

    r1b367b4 r8b1e15ac  
    1 /*
     1/*                       
    22 * Copyright (c) 2010 Lenka Trochtova
    33 * All rights reserved.
     
    178178 *                      error number otherwise.
    179179 */
    180 static int ns8250_read(device_t *dev, char *buf, size_t count)
     180static int ns8250_read(function_t *fun, char *buf, size_t count)
    181181{
    182182        int ret = EOK;
    183         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     183        ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
    184184       
    185185        fibril_mutex_lock(&data->mutex);
     
    212212 * @return              Zero on success.
    213213 */
    214 static int ns8250_write(device_t *dev, char *buf, size_t count)
    215 {
    216         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     214static int ns8250_write(function_t *fun, char *buf, size_t count)
     215{
     216        ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
    217217        size_t idx;
    218218       
     
    719719static int ns8250_add_device(device_t *dev)
    720720{
     721        function_t *fun;
     722
    721723        printf(NAME ": ns8250_add_device %s (handle = %d)\n",
    722724            dev->name, (int) dev->handle);
     
    756758                return res;
    757759        }
     760
     761        fun = create_function();
     762        fun->ftype = fun_exposed;
     763        fun->name = "a";
    758764       
    759765        /* Set device operations. */
    760         dev->ops = &ns8250_dev_ops;
    761        
    762         add_device_to_class(dev, "serial");
     766        fun->ops = &ns8250_dev_ops;
     767        register_function(fun, dev);
     768       
     769        add_function_to_class(fun, "serial");
    763770       
    764771        printf(NAME ": the %s device has been successfully initialized.\n",
     
    775782 * @param dev           The device.
    776783 */
    777 static int ns8250_open(device_t *dev)
    778 {
    779         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     784static int ns8250_open(function_t *fun)
     785{
     786        ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
    780787        int res;
    781788       
     
    799806 * @param dev           The device.
    800807 */
    801 static void ns8250_close(device_t *dev)
    802 {
    803         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     808static void ns8250_close(function_t *fun)
     809{
     810        ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
    804811       
    805812        fibril_mutex_lock(&data->mutex);
     
    877884 * Configure the parameters of the serial communication.
    878885 */
    879 static void ns8250_default_handler(device_t *dev, ipc_callid_t callid,
     886static void ns8250_default_handler(function_t *fun, ipc_callid_t callid,
    880887    ipc_call_t *call)
    881888{
     
    886893        switch (method) {
    887894        case SERIAL_GET_COM_PROPS:
    888                 ns8250_get_props(dev, &baud_rate, &parity, &word_length,
     895                ns8250_get_props(fun->dev, &baud_rate, &parity, &word_length,
    889896                    &stop_bits);
    890897                async_answer_4(callid, EOK, baud_rate, parity, word_length,
     
    897904                word_length = IPC_GET_ARG3(*call);
    898905                stop_bits = IPC_GET_ARG4(*call);
    899                 ret = ns8250_set_props(dev, baud_rate, parity, word_length,
     906                ret = ns8250_set_props(fun->dev, baud_rate, parity, word_length,
    900907                    stop_bits);
    901908                async_answer_0(callid, ret);
  • uspace/drv/pciintel/pci.c

    r1b367b4 r8b1e15ac  
    6161        ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
    6262
    63 static hw_resource_list_t *pciintel_get_child_resources(device_t *dev)
    64 {
    65         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    66        
    67         if (dev_data == NULL)
     63static hw_resource_list_t *pciintel_get_child_resources(function_t *fun)
     64{
     65        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     66       
     67        if (fun_data == NULL)
    6868                return NULL;
    69         return &dev_data->hw_resources;
    70 }
    71 
    72 static bool pciintel_enable_child_interrupt(device_t *dev)
     69        return &fun_data->hw_resources;
     70}
     71
     72static bool pciintel_enable_child_interrupt(function_t *fun)
    7373{
    7474        /* TODO */
     
    122122}
    123123
    124 static void pci_conf_read(device_t *dev, int reg, uint8_t *buf, size_t len)
    125 {
    126         assert(dev->parent != NULL);
    127        
    128         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    129         pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;
     124static void pci_conf_read(function_t *fun, int reg, uint8_t *buf, size_t len)
     125{
     126        assert(fun->dev != NULL);
     127       
     128        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     129        pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data;
    130130       
    131131        fibril_mutex_lock(&bus_data->conf_mutex);
    132132       
    133133        uint32_t conf_addr;
    134         conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg);
     134        conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_data->fn, reg);
    135135        void *addr = bus_data->conf_data_port + (reg & 3);
    136136       
     
    152152}
    153153
    154 static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len)
    155 {
    156         assert(dev->parent != NULL);
    157        
    158         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    159         pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;
     154static void pci_conf_write(function_t *fun, int reg, uint8_t *buf, size_t len)
     155{
     156        assert(fun->dev != NULL);
     157       
     158        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     159        pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data;
    160160       
    161161        fibril_mutex_lock(&bus_data->conf_mutex);
    162162       
    163163        uint32_t conf_addr;
    164         conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg);
     164        conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_data->fn, reg);
    165165        void *addr = bus_data->conf_data_port + (reg & 3);
    166166       
     
    182182}
    183183
    184 uint8_t pci_conf_read_8(device_t *dev, int reg)
     184uint8_t pci_conf_read_8(function_t *fun, int reg)
    185185{
    186186        uint8_t res;
    187         pci_conf_read(dev, reg, &res, 1);
     187        pci_conf_read(fun, reg, &res, 1);
    188188        return res;
    189189}
    190190
    191 uint16_t pci_conf_read_16(device_t *dev, int reg)
     191uint16_t pci_conf_read_16(function_t *fun, int reg)
    192192{
    193193        uint16_t res;
    194         pci_conf_read(dev, reg, (uint8_t *) &res, 2);
     194        pci_conf_read(fun, reg, (uint8_t *) &res, 2);
    195195        return res;
    196196}
    197197
    198 uint32_t pci_conf_read_32(device_t *dev, int reg)
     198uint32_t pci_conf_read_32(function_t *fun, int reg)
    199199{
    200200        uint32_t res;
    201         pci_conf_read(dev, reg, (uint8_t *) &res, 4);
     201        pci_conf_read(fun, reg, (uint8_t *) &res, 4);
    202202        return res;
    203203}
    204204
    205 void pci_conf_write_8(device_t *dev, int reg, uint8_t val)
    206 {
    207         pci_conf_write(dev, reg, (uint8_t *) &val, 1);
    208 }
    209 
    210 void pci_conf_write_16(device_t *dev, int reg, uint16_t val)
    211 {
    212         pci_conf_write(dev, reg, (uint8_t *) &val, 2);
    213 }
    214 
    215 void pci_conf_write_32(device_t *dev, int reg, uint32_t val)
    216 {
    217         pci_conf_write(dev, reg, (uint8_t *) &val, 4);
    218 }
    219 
    220 void create_pci_match_ids(device_t *dev)
    221 {
    222         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
     205void pci_conf_write_8(function_t *fun, int reg, uint8_t val)
     206{
     207        pci_conf_write(fun, reg, (uint8_t *) &val, 1);
     208}
     209
     210void pci_conf_write_16(function_t *fun, int reg, uint16_t val)
     211{
     212        pci_conf_write(fun, reg, (uint8_t *) &val, 2);
     213}
     214
     215void pci_conf_write_32(function_t *fun, int reg, uint32_t val)
     216{
     217        pci_conf_write(fun, reg, (uint8_t *) &val, 4);
     218}
     219
     220void create_pci_match_ids(function_t *fun)
     221{
     222        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    223223        match_id_t *match_id = NULL;
    224224        char *match_id_str;
     
    227227        if (match_id != NULL) {
    228228                asprintf(&match_id_str, "pci/ven=%04x&dev=%04x",
    229                     dev_data->vendor_id, dev_data->device_id);
     229                    fun_data->vendor_id, fun_data->device_id);
    230230                match_id->id = match_id_str;
    231231                match_id->score = 90;
    232                 add_match_id(&dev->match_ids, match_id);
     232                add_match_id(&fun->match_ids, match_id);
    233233        }
    234234
     
    237237
    238238void
    239 pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io)
    240 {
    241         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    242         hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     239pci_add_range(function_t *fun, uint64_t range_addr, size_t range_size, bool io)
     240{
     241        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     242        hw_resource_list_t *hw_res_list = &fun_data->hw_resources;
    243243        hw_resource_t *hw_resources =  hw_res_list->resources;
    244244        size_t count = hw_res_list->count;
     
    270270 * @return      The addr the address of the BAR which should be read next.
    271271 */
    272 int pci_read_bar(device_t *dev, int addr)
     272int pci_read_bar(function_t *fun, int addr)
    273273{       
    274274        /* Value of the BAR */
     
    285285       
    286286        /* Get the value of the BAR. */
    287         val = pci_conf_read_32(dev, addr);
     287        val = pci_conf_read_32(fun, addr);
    288288       
    289289        io = (bool) (val & 1);
     
    305305       
    306306        /* Get the address mask. */
    307         pci_conf_write_32(dev, addr, 0xffffffff);
    308         mask = pci_conf_read_32(dev, addr);
     307        pci_conf_write_32(fun, addr, 0xffffffff);
     308        mask = pci_conf_read_32(fun, addr);
    309309       
    310310        /* Restore the original value. */
    311         pci_conf_write_32(dev, addr, val);
    312         val = pci_conf_read_32(dev, addr);
     311        pci_conf_write_32(fun, addr, val);
     312        val = pci_conf_read_32(fun, addr);
    313313       
    314314        range_size = pci_bar_mask_to_size(mask);
    315315       
    316316        if (addrw64) {
    317                 range_addr = ((uint64_t)pci_conf_read_32(dev, addr + 4) << 32) |
     317                range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) |
    318318                    (val & 0xfffffff0);
    319319        } else {
     
    322322       
    323323        if (range_addr != 0) {
    324                 printf(NAME ": device %s : ", dev->name);
     324                printf(NAME ": function %s : ", fun->name);
    325325                printf("address = %" PRIx64, range_addr);
    326326                printf(", size = %x\n", (unsigned int) range_size);
    327327        }
    328328       
    329         pci_add_range(dev, range_addr, range_size, io);
     329        pci_add_range(fun, range_addr, range_size, io);
    330330       
    331331        if (addrw64)
     
    335335}
    336336
    337 void pci_add_interrupt(device_t *dev, int irq)
    338 {
    339         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    340         hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     337void pci_add_interrupt(function_t *fun, int irq)
     338{
     339        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     340        hw_resource_list_t *hw_res_list = &fun_data->hw_resources;
    341341        hw_resource_t *hw_resources = hw_res_list->resources;
    342342        size_t count = hw_res_list->count;
     
    350350        hw_res_list->count++;
    351351       
    352         printf(NAME ": device %s uses irq %x.\n", dev->name, irq);
    353 }
    354 
    355 void pci_read_interrupt(device_t *dev)
    356 {
    357         uint8_t irq = pci_conf_read_8(dev, PCI_BRIDGE_INT_LINE);
     352        printf(NAME ": function %s uses irq %x.\n", fun->name, irq);
     353}
     354
     355void pci_read_interrupt(function_t *fun)
     356{
     357        uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
    358358        if (irq != 0xff)
    359                 pci_add_interrupt(dev, irq);
     359                pci_add_interrupt(fun, irq);
    360360}
    361361
    362362/** Enumerate (recursively) and register the devices connected to a pci bus.
    363363 *
    364  * @param parent        The host-to-pci bridge device.
     364 * @param dev           The host-to-pci bridge device.
    365365 * @param bus_num       The bus number.
    366366 */
    367 void pci_bus_scan(device_t *parent, int bus_num)
    368 {
    369         device_t *dev = create_device();
    370         pci_dev_data_t *dev_data = create_pci_dev_data();
    371         dev->driver_data = dev_data;
    372         dev->parent = parent;
     367void pci_bus_scan(device_t *dev, int bus_num)
     368{
     369        function_t *fun = create_function();
     370        pci_fun_data_t *fun_data = create_pci_fun_data();
     371        fun->driver_data = fun_data;
    373372       
    374373        int child_bus = 0;
    375374        int dnum, fnum;
    376375        bool multi;
    377         uint8_t header_type;
     376        uint8_t header_type;
     377
     378        /* We need this early, before registering. */
     379        fun->dev = dev;
    378380       
    379381        for (dnum = 0; dnum < 32; dnum++) {
    380382                multi = true;
    381383                for (fnum = 0; multi && fnum < 8; fnum++) {
    382                         init_pci_dev_data(dev_data, bus_num, dnum, fnum);
    383                         dev_data->vendor_id = pci_conf_read_16(dev,
     384                        init_pci_fun_data(fun_data, bus_num, dnum, fnum);
     385                        fun_data->vendor_id = pci_conf_read_16(fun,
    384386                            PCI_VENDOR_ID);
    385                         dev_data->device_id = pci_conf_read_16(dev,
     387                        fun_data->device_id = pci_conf_read_16(fun,
    386388                            PCI_DEVICE_ID);
    387                         if (dev_data->vendor_id == 0xffff) {
     389                        if (fun_data->vendor_id == 0xffff) {
    388390                                /*
    389391                                 * The device is not present, go on scanning the
     
    396398                        }
    397399                       
    398                         header_type = pci_conf_read_8(dev, PCI_HEADER_TYPE);
     400                        header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE);
    399401                        if (fnum == 0) {
    400402                                /* Is the device multifunction? */
     
    404406                        header_type = header_type & 0x7F;
    405407                       
    406                         create_pci_dev_name(dev);
    407                        
    408                         pci_alloc_resource_list(dev);
    409                         pci_read_bars(dev);
    410                         pci_read_interrupt(dev);
    411                        
    412                         dev->ops = &pci_child_ops;
    413                        
    414                         printf(NAME ": adding new child device %s.\n",
    415                             dev->name);
    416                        
    417                         create_pci_match_ids(dev);
    418                        
    419                         if (child_device_register(dev, parent) != EOK) {
    420                                 pci_clean_resource_list(dev);
    421                                 clean_match_ids(&dev->match_ids);
    422                                 free((char *) dev->name);
    423                                 dev->name = NULL;
     408                        create_pci_fun_name(fun);
     409                       
     410                        pci_alloc_resource_list(fun);
     411                        pci_read_bars(fun);
     412                        pci_read_interrupt(fun);
     413                       
     414                        fun->ftype = fun_inner;
     415                        fun->ops = &pci_child_ops;
     416                       
     417                        printf(NAME ": adding new function %s.\n",
     418                            fun->name);
     419                       
     420                        create_pci_match_ids(fun);
     421                       
     422                        if (register_function(fun, dev) != EOK) {
     423                                pci_clean_resource_list(fun);
     424                                clean_match_ids(&fun->match_ids);
     425                                free((char *) fun->name);
     426                                fun->name = NULL;
    424427                                continue;
    425428                        }
     
    427430                        if (header_type == PCI_HEADER_TYPE_BRIDGE ||
    428431                            header_type == PCI_HEADER_TYPE_CARDBUS) {
    429                                 child_bus = pci_conf_read_8(dev,
     432                                child_bus = pci_conf_read_8(fun,
    430433                                    PCI_BRIDGE_SEC_BUS_NUM);
    431434                                printf(NAME ": device is pci-to-pci bridge, "
    432435                                    "secondary bus number = %d.\n", bus_num);
    433436                                if (child_bus > bus_num)
    434                                         pci_bus_scan(parent, child_bus);
     437                                        pci_bus_scan(dev, child_bus);
    435438                        }
    436439                       
    437                         /* Alloc new aux. dev. structure. */
    438                         dev = create_device();
    439                         dev_data = create_pci_dev_data();
    440                         dev->driver_data = dev_data;
    441                         dev->parent = parent;
     440                        /* Alloc new aux. fun. structure. */
     441                        fun = create_function();
     442
     443                        /* We need this early, before registering. */
     444                        fun->dev = dev;
     445
     446                        fun_data = create_pci_fun_data();
     447                        fun->driver_data = fun_data;
    442448                }
    443449        }
    444450       
    445         if (dev_data->vendor_id == 0xffff) {
    446                 delete_device(dev);
    447                 /* Free the auxiliary device structure. */
    448                 delete_pci_dev_data(dev_data);
     451        if (fun_data->vendor_id == 0xffff) {
     452                delete_function(fun);
     453                /* Free the auxiliary function structure. */
     454                delete_pci_fun_data(fun_data);
    449455        }
    450456}
     
    504510        dev->driver_data = bus_data;
    505511       
     512        /* Make the bus device more visible. Does not do anything. */
     513        printf(NAME ": adding a 'ctl' function\n");
     514
     515        function_t *ctl = create_function();
     516        ctl->ftype = fun_exposed;
     517        ctl->name = "ctl";
     518        register_function(ctl, dev);
     519       
    506520        /* Enumerate child devices. */
    507521        printf(NAME ": scanning the bus\n");
     
    518532}
    519533
    520 pci_dev_data_t *create_pci_dev_data(void)
    521 {
    522         pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t));
     534pci_fun_data_t *create_pci_fun_data(void)
     535{
     536        pci_fun_data_t *res = (pci_fun_data_t *) malloc(sizeof(pci_fun_data_t));
    523537       
    524538        if (res != NULL)
    525                 memset(res, 0, sizeof(pci_dev_data_t));
     539                memset(res, 0, sizeof(pci_fun_data_t));
    526540        return res;
    527541}
    528542
    529 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn)
    530 {
    531         dev_data->bus = bus;
    532         dev_data->dev = dev;
    533         dev_data->fn = fn;
    534 }
    535 
    536 void delete_pci_dev_data(pci_dev_data_t *dev_data)
    537 {
    538         if (dev_data != NULL) {
    539                 hw_res_clean_resource_list(&dev_data->hw_resources);
    540                 free(dev_data);
    541         }
    542 }
    543 
    544 void create_pci_dev_name(device_t *dev)
    545 {
    546         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
     543void init_pci_fun_data(pci_fun_data_t *fun_data, int bus, int dev, int fn)
     544{
     545        fun_data->bus = bus;
     546        fun_data->dev = dev;
     547        fun_data->fn = fn;
     548}
     549
     550void delete_pci_fun_data(pci_fun_data_t *fun_data)
     551{
     552        if (fun_data != NULL) {
     553                hw_res_clean_resource_list(&fun_data->hw_resources);
     554                free(fun_data);
     555        }
     556}
     557
     558void create_pci_fun_name(function_t *fun)
     559{
     560        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    547561        char *name = NULL;
    548562       
    549         asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev,
    550             dev_data->fn);
    551         dev->name = name;
    552 }
    553 
    554 bool pci_alloc_resource_list(device_t *dev)
    555 {
    556         pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
    557        
    558         dev_data->hw_resources.resources =
     563        asprintf(&name, "%02x:%02x.%01x", fun_data->bus, fun_data->dev,
     564            fun_data->fn);
     565        fun->name = name;
     566}
     567
     568bool pci_alloc_resource_list(function_t *fun)
     569{
     570        pci_fun_data_t *fun_data = (pci_fun_data_t *)fun->driver_data;
     571       
     572        fun_data->hw_resources.resources =
    559573            (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t));
    560         return dev_data->hw_resources.resources != NULL;
    561 }
    562 
    563 void pci_clean_resource_list(device_t *dev)
    564 {
    565         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    566        
    567         if (dev_data->hw_resources.resources != NULL) {
    568                 free(dev_data->hw_resources.resources);
    569                 dev_data->hw_resources.resources = NULL;
     574        return fun_data->hw_resources.resources != NULL;
     575}
     576
     577void pci_clean_resource_list(function_t *fun)
     578{
     579        pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     580       
     581        if (fun_data->hw_resources.resources != NULL) {
     582                free(fun_data->hw_resources.resources);
     583                fun_data->hw_resources.resources = NULL;
    570584        }
    571585}
     
    576590 * @param dev the pci device.
    577591 */
    578 void pci_read_bars(device_t *dev)
     592void pci_read_bars(function_t *fun)
    579593{
    580594        /*
     
    585599       
    586600        while (addr <= PCI_BASE_ADDR_5)
    587                 addr = pci_read_bar(dev, addr);
     601                addr = pci_read_bar(fun, addr);
    588602}
    589603
  • uspace/drv/pciintel/pci.h

    r1b367b4 r8b1e15ac  
    4444#define PCI_MAX_HW_RES 8
    4545
    46 typedef struct pci_dev_data {
     46typedef struct pci_fun_data {
    4747        int bus;
    4848        int dev;
     
    5151        int device_id;
    5252        hw_resource_list_t hw_resources;
    53 } pci_dev_data_t;
     53} pci_fun_data_t;
    5454
    55 extern void create_pci_match_ids(device_t *);
     55extern void create_pci_match_ids(function_t *);
    5656
    57 extern uint8_t pci_conf_read_8(device_t *, int);
    58 extern uint16_t pci_conf_read_16(device_t *, int);
    59 extern uint32_t pci_conf_read_32(device_t *, int);
    60 extern void pci_conf_write_8(device_t *, int, uint8_t);
    61 extern void pci_conf_write_16(device_t *, int, uint16_t);
    62 extern void pci_conf_write_32(device_t *, int, uint32_t);
     57extern uint8_t pci_conf_read_8(function_t *, int);
     58extern uint16_t pci_conf_read_16(function_t *, int);
     59extern uint32_t pci_conf_read_32(function_t *, int);
     60extern void pci_conf_write_8(function_t *, int, uint8_t);
     61extern void pci_conf_write_16(function_t *, int, uint16_t);
     62extern void pci_conf_write_32(function_t *, int, uint32_t);
    6363
    64 extern void pci_add_range(device_t *, uint64_t, size_t, bool);
    65 extern int pci_read_bar(device_t *, int);
    66 extern void pci_read_interrupt(device_t *);
    67 extern void pci_add_interrupt(device_t *, int);
     64extern void pci_add_range(function_t *, uint64_t, size_t, bool);
     65extern int pci_read_bar(function_t *, int);
     66extern void pci_read_interrupt(function_t *);
     67extern void pci_add_interrupt(function_t *, int);
    6868
    6969extern void pci_bus_scan(device_t *, int);
    7070
    71 extern pci_dev_data_t *create_pci_dev_data(void);
    72 extern void init_pci_dev_data(pci_dev_data_t *, int, int, int);
    73 extern void delete_pci_dev_data(pci_dev_data_t *);
    74 extern void create_pci_dev_name(device_t *);
     71extern pci_fun_data_t *create_pci_fun_data(void);
     72extern void init_pci_fun_data(pci_fun_data_t *, int, int, int);
     73extern void delete_pci_fun_data(pci_fun_data_t *);
     74extern void create_pci_fun_name(function_t *);
    7575
    76 extern bool pci_alloc_resource_list(device_t *);
    77 extern void pci_clean_resource_list(device_t *);
     76extern bool pci_alloc_resource_list(function_t *);
     77extern void pci_clean_resource_list(function_t *);
    7878
    79 extern void pci_read_bars(device_t *);
     79extern void pci_read_bars(function_t *);
    8080extern size_t pci_bar_mask_to_size(uint32_t);
    8181
  • uspace/drv/root/root.c

    r1b367b4 r8b1e15ac  
    8787            VIRTUAL_DEVICE_MATCH_SCORE, VIRTUAL_DEVICE_MATCH_ID);
    8888
    89         int res = child_device_register_wrapper(parent, VIRTUAL_DEVICE_NAME,
     89        int res = register_function_wrapper(parent, VIRTUAL_DEVICE_NAME,
    9090            VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE);
    9191
     
    135135            PLATFORM_DEVICE_MATCH_SCORE, match_id);
    136136
    137         res = child_device_register_wrapper(parent, PLATFORM_DEVICE_NAME,
     137        res = register_function_wrapper(parent, PLATFORM_DEVICE_NAME,
    138138            match_id, PLATFORM_DEVICE_MATCH_SCORE);
    139139
  • uspace/drv/rootpc/rootpc.c

    r1b367b4 r8b1e15ac  
    5555#define NAME "rootpc"
    5656
    57 typedef struct rootpc_child_dev_data {
     57typedef struct rootpc_fun_data {
    5858        hw_resource_list_t hw_resources;
    59 } rootpc_child_dev_data_t;
     59} rootpc_fun_data_t;
    6060
    6161static int rootpc_add_device(device_t *dev);
     
    8282};
    8383
    84 static rootpc_child_dev_data_t pci_data = {
     84static rootpc_fun_data_t pci_data = {
    8585        .hw_resources = {
    8686                1,
     
    8989};
    9090
    91 static hw_resource_list_t *rootpc_get_child_resources(device_t *dev)
    92 {
    93         rootpc_child_dev_data_t *data;
    94        
    95         data = (rootpc_child_dev_data_t *) dev->driver_data;
     91static hw_resource_list_t *rootpc_get_fun_resources(function_t *fun)
     92{
     93        rootpc_fun_data_t *data;
     94       
     95        data = (rootpc_fun_data_t *) fun->driver_data;
    9696        if (NULL == data)
    9797                return NULL;
     
    100100}
    101101
    102 static bool rootpc_enable_child_interrupt(device_t *dev)
     102static bool rootpc_enable_fun_interrupt(function_t *fun)
    103103{
    104104        /* TODO */
     
    107107}
    108108
    109 static hw_res_ops_t child_hw_res_ops = {
    110         &rootpc_get_child_resources,
    111         &rootpc_enable_child_interrupt
     109static hw_res_ops_t fun_hw_res_ops = {
     110        &rootpc_get_fun_resources,
     111        &rootpc_enable_fun_interrupt
    112112};
    113113
    114114/* Initialized in root_pc_init() function. */
    115 static device_ops_t rootpc_child_ops;
     115static device_ops_t rootpc_fun_ops;
    116116
    117117static bool
    118 rootpc_add_child(device_t *parent, const char *name, const char *str_match_id,
    119     rootpc_child_dev_data_t *drv_data)
    120 {
    121         printf(NAME ": adding new child device '%s'.\n", name);
    122        
    123         device_t *child = NULL;
     118rootpc_add_fun(device_t *parent, const char *name, const char *str_match_id,
     119    rootpc_fun_data_t *drv_data)
     120{
     121        printf(NAME ": adding new function '%s'.\n", name);
     122       
     123        function_t *fun = NULL;
    124124        match_id_t *match_id = NULL;
    125125       
    126126        /* Create new device. */
    127         child = create_device();
    128         if (NULL == child)
     127        fun = create_function();
     128        if (fun == NULL)
    129129                goto failure;
    130130       
    131         child->name = name;
    132         child->driver_data = drv_data;
     131        fun->name = name;
     132        fun->driver_data = drv_data;
     133        fun->ftype = fun_inner;
    133134       
    134135        /* Initialize match id list */
     
    139140        match_id->id = str_match_id;
    140141        match_id->score = 100;
    141         add_match_id(&child->match_ids, match_id);
     142        add_match_id(&fun->match_ids, match_id);
    142143       
    143144        /* Set provided operations to the device. */
    144         child->ops = &rootpc_child_ops;
    145        
    146         /* Register child device. */
    147         if (EOK != child_device_register(child, parent))
     145        fun->ops = &rootpc_fun_ops;
     146       
     147        /* Register function. */
     148        if (EOK != register_function(fun, parent))
    148149                goto failure;
     150        printf(NAME ": registered function handle = %u\n", fun->handle);
    149151       
    150152        return true;
     
    154156                match_id->id = NULL;
    155157       
    156         if (NULL != child) {
    157                 child->name = NULL;
    158                 delete_device(child);
    159         }
    160        
    161         printf(NAME ": failed to add child device '%s'.\n", name);
     158        if (NULL != fun) {
     159                fun->name = NULL;
     160                delete_function(fun);
     161        }
     162       
     163        printf(NAME ": failed to add function '%s'.\n", name);
    162164       
    163165        return false;
    164166}
    165167
    166 static bool rootpc_add_children(device_t *dev)
    167 {
    168         return rootpc_add_child(dev, "pci0", "intel_pci", &pci_data);
     168static bool rootpc_add_functions(device_t *dev)
     169{
     170        return rootpc_add_fun(dev, "pci0", "intel_pci", &pci_data);
    169171}
    170172
     
    180182            (int)dev->handle);
    181183       
    182         /* Register child devices. */
    183         if (!rootpc_add_children(dev)) {
    184                 printf(NAME ": failed to add child devices for PC platform.\n");
     184        /* Register functions. */
     185        if (!rootpc_add_functions(dev)) {
     186                printf(NAME ": failed to add functions for PC platform.\n");
    185187        }
    186188       
     
    190192static void root_pc_init(void)
    191193{
    192         rootpc_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_hw_res_ops;
     194        rootpc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
    193195}
    194196
  • uspace/drv/rootvirt/rootvirt.c

    r1b367b4 r8b1e15ac  
    4343#define NAME "rootvirt"
    4444
    45 /** Virtual device entry. */
     45/** Virtual function entry */
    4646typedef struct {
    47         /** Device name. */
     47        /** Function name */
    4848        const char *name;
    49         /** Device match id. */
     49        /** Function match ID */
    5050        const char *match_id;
    51 } virtual_device_t;
     51} virtual_function_t;
    5252
    53 /** List of existing virtual devices. */
    54 virtual_device_t virtual_devices[] = {
     53/** List of existing virtual functions */
     54virtual_function_t virtual_functions[] = {
    5555#include "devices.def"
    56         /* Terminating item. */
     56        /* Terminating item */
    5757        {
    5858                .name = NULL,
     
    7272};
    7373
    74 /** Add child device.
     74/** Add function to the virtual device.
    7575 *
    76  * @param parent Parent device.
    77  * @param virt_dev Virtual device to add.
    78  * @return Error code.
     76 * @param vdev          The virtual device
     77 * @param vfun          Virtual function description
     78 * @return              EOK on success or negative error code.
    7979 */
    80 static int add_child(device_t *parent, virtual_device_t *virt_dev)
     80static int add_child(device_t *vdev, virtual_function_t *vfun)
    8181{
    82         printf(NAME ": registering child device `%s' (match \"%s\")\n",
    83             virt_dev->name, virt_dev->match_id);
     82        printf(NAME ": registering function `%s' (match \"%s\")\n",
     83            vfun->name, vfun->match_id);
    8484
    85         int rc = child_device_register_wrapper(parent, virt_dev->name,
    86             virt_dev->match_id, 10);
     85        int rc = register_function_wrapper(vdev, vfun->name,
     86            vfun->match_id, 10);
    8787
    8888        if (rc == EOK) {
    8989                printf(NAME ": registered child device `%s'\n",
    90                     virt_dev->name);
     90                    vfun->name);
    9191        } else {
    9292                printf(NAME ": failed to register child device `%s': %s\n",
    93                     virt_dev->name, str_error(rc));
     93                    vfun->name, str_error(rc));
    9494        }
    9595
     
    109109        }
    110110
    111         printf(NAME ": add_device(name=\"%s\", handle=%d)\n",
    112             dev->name, (int)dev->handle);
     111        printf(NAME ": add_device(handle=%d)\n", (int)dev->handle);
    113112       
    114113        /*
    115          * Go through all virtual devices and try to add them.
     114         * Go through all virtual functions and try to add them.
    116115         * We silently ignore failures.
    117116         */
    118         virtual_device_t *virt_dev = virtual_devices;
    119         while (virt_dev->name != NULL) {
    120                 (void) add_child(dev, virt_dev);
    121                 virt_dev++;
     117        virtual_function_t *vfun = virtual_functions;
     118        while (vfun->name != NULL) {
     119                (void) add_child(dev, vfun);
     120                vfun++;
    122121        }
    123122
  • uspace/drv/test1/char.c

    r1b367b4 r8b1e15ac  
    3737#include "test1.h"
    3838
    39 static int impl_char_read(device_t *dev, char *buf, size_t count) {
     39static int impl_char_read(function_t *fun, char *buf, size_t count) {
    4040        memset(buf, 0, count);
    4141        return count;
    4242}
    4343
    44 static int imp_char_write(device_t *dev, char *buf, size_t count) {
     44static int imp_char_write(function_t *fun, char *buf, size_t count) {
    4545        return count;
    4646}
  • uspace/drv/test1/test1.c

    r1b367b4 r8b1e15ac  
    6161           name, message);
    6262
    63         int rc = child_device_register_wrapper(parent, name,
     63        int rc = register_function_wrapper(parent, name,
    6464            match_id, match_score);
    6565
    6666        if (rc == EOK) {
    67                 printf(NAME ": registered child device `%s'.\n", name);
     67                printf(NAME ": registered function `%s'.\n", name);
    6868        } else {
    69                 printf(NAME ": failed to register child `%s' (%s).\n",
     69                printf(NAME ": failed to register function `%s' (%s).\n",
    7070                    name, str_error(rc));
    7171        }
     
    9191static int add_device(device_t *dev)
    9292{
     93        function_t *fun_a;
     94
    9395        printf(NAME ": add_device(name=\"%s\", handle=%d)\n",
    9496            dev->name, (int) dev->handle);
    9597
    96         add_device_to_class(dev, "virtual");
     98        fun_a = create_function();
     99        fun_a->ftype = fun_exposed;
     100        fun_a->name = "a";
     101
     102        register_function(fun_a, dev);
     103
     104        add_function_to_class(fun_a, "virtual");
    97105
    98106        if (str_cmp(dev->name, "null") == 0) {
    99                 dev->ops = &char_device_ops;
    100                 add_device_to_class(dev, "virt-null");
    101         } else if (dev->parent == NULL) {
     107                fun_a->ops = &char_device_ops;
     108                add_function_to_class(fun_a, "virt-null");
     109        } else if (str_cmp(dev->name, "test1") == 0) {
    102110                register_child_verbose(dev, "cloning myself ;-)", "clone",
    103111                    "virtual&test1", 10);
  • uspace/drv/test2/test2.c

    r1b367b4 r8b1e15ac  
    6363           name, message);
    6464
    65         int rc = child_device_register_wrapper(parent, name,
     65        int rc = register_function_wrapper(parent, name,
    6666            match_id, match_score);
    6767
     
    8282{
    8383        device_t *dev = (device_t *) arg;
     84        function_t *fun;
    8485
    8586        async_usleep(1000);
     
    9091            "test1", "virtual&test1", 10);
    9192
    92         add_device_to_class(dev, "virtual");
     93        fun = create_function();
     94        fun->ftype = fun_exposed;
     95        fun->name = "a";
     96
     97        register_function(fun, dev);
     98
     99        add_function_to_class(fun, "virtual");
    93100
    94101        return EOK;
    95102}
    96 
    97103
    98104static int add_device(device_t *dev)
     
    101107            dev->name, (int) dev->handle);
    102108
    103         if (dev->parent == NULL) {
     109        if (str_cmp(dev->name, "child") != 0) {
    104110                fid_t postpone = fibril_create(postponed_birth, dev);
    105111                if (postpone == 0) {
  • uspace/lib/c/generic/devman.c

    r1b367b4 r8b1e15ac  
    158158}
    159159
    160 int devman_child_device_register(const char *name, match_id_list_t *match_ids,
    161     devman_handle_t parent_handle, devman_handle_t *handle)
     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)
    162175{
    163176        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
     177        int fun_handle;
    164178       
    165179        if (phone < 0)
     
    168182        async_serialize_start();
    169183       
    170         int match_count = list_count(&match_ids->ids); 
    171         ipc_call_t answer;
    172         aid_t req = async_send_2(phone, DEVMAN_ADD_CHILD_DEVICE, parent_handle, match_count,
    173             &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);
    174189
    175190        sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     
    186201        async_serialize_end();
    187202       
    188         if (retval != EOK) {
    189                 if (handle != NULL)
    190                         *handle = -1;
    191 
    192                 return retval;
    193         }
    194        
    195         if (handle != NULL)
    196                 *handle = (int) IPC_GET_ARG1(answer);
    197                
     203        if (retval == EOK)
     204                fun_handle = (int) IPC_GET_ARG1(answer);
     205        else
     206                fun_handle = -1;
     207       
     208        *funh = fun_handle;
     209
    198210        return retval;
    199211}
  • uspace/lib/c/include/devman.h

    r1b367b4 r8b1e15ac  
    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

    r1b367b4 r8b1e15ac  
    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/drv/generic/driver.c

    r1b367b4 r8b1e15ac  
    5959
    6060/** Devices */
    61 LIST_INITIALIZE(devices);
    62 FIBRIL_MUTEX_INITIALIZE(devices_mutex);
     61LIST_INITIALIZE(functions);
     62FIBRIL_MUTEX_INITIALIZE(functions_mutex);
    6363
    6464/** Interrupts */
     
    209209}
    210210
    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;
     211static void add_to_functions_list(function_t *fun)
     212{
     213        fibril_mutex_lock(&functions_mutex);
     214        list_append(&fun->link, &functions);
     215        fibril_mutex_unlock(&functions_mutex);
     216}
     217
     218static void remove_from_functions_list(function_t *fun)
     219{
     220        fibril_mutex_lock(&functions_mutex);
     221        list_remove(&fun->link);
     222        fibril_mutex_unlock(&functions_mutex);
     223}
     224
     225static function_t *driver_get_function(link_t *functions, devman_handle_t handle)
     226{
     227        function_t *fun = NULL;
     228        printf("driver_get_function handle=%" PRIun "\n", handle);
     229       
     230        fibril_mutex_lock(&functions_mutex);
     231        link_t *link = functions->next;
     232       
     233        while (link != functions) {
     234                fun = list_get_instance(link, function_t, link);
     235                printf(" - fun handle %" PRIun "\n", fun->handle);
     236                if (fun->handle == handle) {
     237                        fibril_mutex_unlock(&functions_mutex);
     238                        return fun;
    237239                }
     240               
    238241                link = link->next;
    239242        }
    240243       
    241         fibril_mutex_unlock(&devices_mutex);
     244        fibril_mutex_unlock(&functions_mutex);
    242245       
    243246        return NULL;
     
    250253       
    251254        devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
    252         devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
     255        devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
    253256       
    254257        device_t *dev = create_device();
    255258        dev->handle = dev_handle;
    256        
     259
    257260        async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);
    258261        dev->name = dev_name;
    259        
    260         add_to_devices_list(dev);
    261         dev->parent = driver_get_device(&devices, parent_dev_handle);
     262
     263        /*
     264         * Currently not used, parent fun handle is stored in context
     265         * of the connection to the parent device driver.
     266         */
     267        (void) parent_fun_handle;
    262268       
    263269        res = driver->driver_ops->add_device(dev);
     
    268274                printf("%s: failed to add a new device with handle = %" PRIun ".\n",
    269275                    driver->name, dev_handle);
    270                 remove_from_devices_list(dev);
    271276                delete_device(dev);
    272277        }
     
    311316         */
    312317        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"
     318        function_t *fun = driver_get_function(&functions, handle);
     319
     320        if (fun == NULL) {
     321                printf("%s: driver_connection_gen error - no function with handle"
    317322                    " %" PRIun " was found.\n", driver->name, handle);
    318323                async_answer_0(iid, ENOENT);
     
    327332       
    328333        int ret = EOK;
    329         /* open the device */
    330         if (dev->ops != NULL && dev->ops->open != NULL)
    331                 ret = (*dev->ops->open)(dev);
     334        /* Open device function */
     335        if (fun->ops != NULL && fun->ops->open != NULL)
     336                ret = (*fun->ops->open)(fun);
    332337       
    333338        async_answer_0(iid, ret);
     
    344349                switch  (method) {
    345350                case IPC_M_PHONE_HUNGUP:
    346                         /* close the device */
    347                         if (dev->ops != NULL && dev->ops->close != NULL)
    348                                 (*dev->ops->close)(dev);
     351                        /* Close device function */
     352                        if (fun->ops != NULL && fun->ops->close != NULL)
     353                                (*fun->ops->close)(fun);
    349354                        async_answer_0(callid, EOK);
    350355                        return;
     
    356361                        if (!is_valid_iface_idx(iface_idx)) {
    357362                                remote_handler_t *default_handler =
    358                                     device_get_default_handler(dev);
     363                                    function_get_default_handler(fun);
    359364                                if (default_handler != NULL) {
    360                                         (*default_handler)(dev, callid, &call);
     365                                        (*default_handler)(fun, callid, &call);
    361366                                        break;
    362367                                }
     368                               
    363369                                /*
    364                                  * This is not device's interface and the
     370                                 * Function has no such interface and
    365371                                 * default handler is not provided.
    366372                                 */
     
    372378                        }
    373379                       
    374                         /* calling one of the device's interfaces */
     380                        /* calling one of the function's interfaces */
    375381                       
    376382                        /* Get the interface ops structure. */
    377                         void *ops = device_get_ops(dev, iface_idx);
     383                        void *ops = function_get_ops(fun, iface_idx);
    378384                        if (ops == NULL) {
    379385                                printf("%s: driver_connection_gen error - ",
    380386                                    driver->name);
    381                                 printf("device with handle %" PRIun " has no interface "
     387                                printf("Function with handle %" PRIun " has no interface "
    382388                                    "with id %d.\n", handle, iface_idx);
    383389                                async_answer_0(callid, ENOTSUP);
     
    408414                         * receive parameters from the remote client and it will
    409415                         * pass it to the corresponding local interface method
    410                          * associated with the device by its driver.
     416                         * associated with the function by its driver.
    411417                         */
    412                         (*iface_method_ptr)(dev, ops, callid, &call);
     418                        (*iface_method_ptr)(fun, ops, callid, &call);
    413419                        break;
    414420                }
     
    425431        driver_connection_gen(iid, icall, false);
    426432}
    427 
    428433
    429434/** Function for handling connections to device driver. */
     
    456461device_t *create_device(void)
    457462{
    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 
     463        device_t *dev;
     464
     465        dev = malloc(sizeof(device_t));
     466        if (dev == NULL)
     467                return NULL;
     468
     469        memset(dev, 0, sizeof(device_t));
    465470        return dev;
    466471}
    467472
     473/** Create new function structure.
     474 *
     475 * @return              The device structure.
     476 */
     477function_t *create_function(void)
     478{
     479        function_t *fun;
     480
     481        fun = malloc(sizeof(function_t));
     482        if (fun == NULL)
     483                return NULL;
     484
     485        memset(fun, 0, sizeof(device_t));
     486
     487        init_match_ids(&fun->match_ids);
     488        link_initialize(&fun->link);
     489
     490        return fun;
     491}
     492
    468493/** Delete device structure.
    469494 *
     
    472497void delete_device(device_t *dev)
    473498{
    474         clean_match_ids(&dev->match_ids);
    475         if (dev->name != NULL)
    476                 free(dev->name);
    477499        free(dev);
    478500}
    479501
    480 void *device_get_ops(device_t *dev, dev_inferface_idx_t idx)
     502/** Delete device structure.
     503 *
     504 * @param dev           The device structure.
     505 */
     506void delete_function(function_t *fun)
     507{
     508        clean_match_ids(&fun->match_ids);
     509        if (fun->name != NULL)
     510                free(fun->name);
     511        free(fun);
     512}
     513
     514void *function_get_ops(function_t *fun, dev_inferface_idx_t idx)
    481515{
    482516        assert(is_valid_iface_idx(idx));
    483         if (dev->ops == NULL)
     517        if (fun->ops == NULL)
    484518                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);
     519        return fun->ops->interfaces[idx];
     520}
     521
     522int register_function(function_t *fun, device_t *dev)
     523{
     524        assert(fun->name != NULL);
    491525       
    492526        int res;
    493527       
    494         add_to_devices_list(child);
    495         res = devman_child_device_register(child->name, &child->match_ids,
    496             parent->handle, &child->handle);
     528        fun->dev = dev;
     529       
     530        add_to_functions_list(fun);
     531        res = devman_add_function(fun->name, fun->ftype, &fun->match_ids,
     532            dev->handle, &fun->handle);
    497533        if (res != EOK) {
    498                 remove_from_devices_list(child);
     534                remove_from_functions_list(fun);
    499535                return res;
    500536        }
     
    511547 * @return Error code.
    512548 */
    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;
     549int register_function_wrapper(device_t *dev, const char *fun_name,
     550    const char *match_id, int match_score)
     551{
     552        function_t *fun = NULL;
     553        match_id_t *m_id = NULL;
    518554        int rc;
    519555       
    520         child = create_device();
    521         if (child == NULL) {
     556        fun = create_function();
     557        if (fun == NULL) {
    522558                rc = ENOMEM;
    523559                goto failure;
    524560        }
    525561       
    526         child->name = child_name;
    527        
    528         match_id = create_match_id();
    529         if (match_id == NULL) {
     562        fun->dev = dev;
     563        fun->name = fun_name;
     564        fun->ftype = fun_inner;
     565       
     566        m_id = create_match_id();
     567        if (m_id == NULL) {
    530568                rc = ENOMEM;
    531569                goto failure;
    532570        }
    533571       
    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);
     572        m_id->id = match_id;
     573        m_id->score = match_score;
     574        add_match_id(&fun->match_ids, m_id);
     575       
     576        rc = register_function(fun, dev);
    539577        if (rc != EOK)
    540578                goto failure;
     
    543581       
    544582failure:
    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);
     583        if (m_id != NULL) {
     584                m_id->id = NULL;
     585                delete_match_id(m_id);
     586        }
     587       
     588        if (fun != NULL) {
     589                fun->name = NULL;
     590                delete_function(fun);
    553591        }
    554592       
     
    557595
    558596/** Get default handler for client requests */
    559 remote_handler_t *device_get_default_handler(device_t *dev)
    560 {
    561         if (dev->ops == NULL)
     597remote_handler_t *function_get_default_handler(function_t *fun)
     598{
     599        if (fun->ops == NULL)
    562600                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);
     601        return fun->ops->default_handler;
     602}
     603
     604int add_function_to_class(function_t *fun, const char *class_name)
     605{
     606        return devman_add_device_to_class(fun->handle, class_name);
    569607}
    570608
  • uspace/lib/drv/generic/remote_char_dev.c

    r1b367b4 r8b1e15ac  
    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(function_t *, void *, ipc_callid_t, ipc_call_t *);
     44static void remote_char_write(function_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(function_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(function_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

    r1b367b4 r8b1e15ac  
    3939#include "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(function_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(function_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(function_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(function_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/dev_iface.h

    r1b367b4 r8b1e15ac  
    4343 */
    4444
    45 struct device;
     45struct function;
    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 function *, 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 function *, ipc_callid_t, ipc_call_t *);
    5555
    5656typedef struct {
  • uspace/lib/drv/include/driver.h

    r1b367b4 r8b1e15ac  
    5252typedef struct device device_t;
    5353
     54struct function;
     55typedef struct function function_t;
     56
    5457/*
    5558 * Device class
     
    6265         * device.
    6366         */
    64         int (*open)(device_t *);
     67        int (*open)(function_t *);
    6568       
    6669        /**
     
    6871         * the device.
    6972         */
    70         void (*close)(device_t *);
     73        void (*close)(function_t *);
    7174       
    7275        /** The table of standard interfaces implemented by the device. */
     
    100103        int parent_phone;
    101104       
    102         /** Parent device if handled by this driver, NULL otherwise */
    103         device_t *parent;
    104105        /** Device name */
    105106        const char *name;
    106         /** List of device ids for device-to-driver matching */
    107         match_id_list_t match_ids;
     107       
    108108        /** Driver-specific data associated with this device */
    109109        void *driver_data;
    110         /** The implementation of operations provided by this device */
     110       
     111        /** Link in the list of devices handled by the driver */
     112        link_t link;
     113};
     114
     115/** Function structure */
     116struct function {
     117        /** Function indentifier (asigned by device manager) */
     118        devman_handle_t handle;
     119       
     120        /** Device which this function belogs to */
     121        device_t *dev;
     122       
     123        /** Function type */
     124        fun_type_t ftype;
     125        /** Function name */
     126        const char *name;
     127        /** List of device ids for driver matching */
     128        match_id_list_t match_ids;
     129        /** Driver-specific data associated with this function */
     130        void *driver_data;
     131        /** Implementation of operations provided by this function */
    111132        device_ops_t *ops;
    112133       
    113         /** Link in the list of devices handled by the driver */
     134        /** Link in the list of functions handled by the driver */
    114135        link_t link;
    115136};
     
    142163extern device_t *create_device(void);
    143164extern void delete_device(device_t *);
    144 extern void *device_get_ops(device_t *, dev_inferface_idx_t);
    145 
    146 extern int child_device_register(device_t *, device_t *);
    147 extern int child_device_register_wrapper(device_t *, const char *, const char *,
     165extern function_t *create_function(void);
     166extern void delete_function(function_t *);
     167extern void *function_get_ops(function_t *, dev_inferface_idx_t);
     168
     169extern int register_function(function_t *, device_t *);
     170extern int register_function_wrapper(device_t *, const char *, const char *,
    148171    int);
    149172
     
    184207extern int unregister_interrupt_handler(device_t *, int);
    185208
    186 extern remote_handler_t *device_get_default_handler(device_t *);
    187 extern int add_device_to_class(device_t *, const char *);
     209extern remote_handler_t *function_get_default_handler(function_t *);
     210extern int add_function_to_class(function_t *fun, const char *class_name);
    188211
    189212#endif
  • uspace/lib/drv/include/ops/char_dev.h

    r1b367b4 r8b1e15ac  
    3939
    4040typedef struct {
    41         int (*read)(device_t *, char *, size_t);
    42         int (*write)(device_t *, char *, size_t);
     41        int (*read)(function_t *, char *, size_t);
     42        int (*write)(function_t *, char *, size_t);
    4343} char_dev_ops_t;
    4444
  • uspace/lib/drv/include/ops/hw_res.h

    r1b367b4 r8b1e15ac  
    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)(function_t *);
     45         bool (*enable_interrupt)(function_t *);
    4646} hw_res_ops_t;
    4747
  • uspace/srv/devman/devman.c

    r1b367b4 r8b1e15ac  
    709709
    710710/** Create devmap path and name for the function. */
    711 static void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree)
     711void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree)
    712712{
    713713        char *devmap_pathname = NULL;
     
    777777        case EOK:
    778778                dev->state = DEVICE_USABLE;
    779                 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    780                 if (0) devmap_register_tree_function(NULL, tree);
    781                 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    782779                break;
    783780        case ENOENT:
  • uspace/srv/devman/devman.h

    r1b367b4 r8b1e15ac  
    363363/* Devmap devices */
    364364
     365extern void devmap_register_tree_function(fun_node_t *, dev_tree_t *);
     366
    365367extern fun_node_t *find_devmap_tree_function(dev_tree_t *, devmap_handle_t);
    366368extern fun_node_t *find_devmap_class_function(class_list_t *, devmap_handle_t);
  • uspace/srv/devman/main.c

    r1b367b4 r8b1e15ac  
    204204}
    205205
    206 /** Handle child device registration.
     206/** Handle function registration.
    207207 *
    208208 * Child devices are registered by their parent's device driver.
    209209 */
    210 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call)
    211 {
    212         devman_handle_t parent_handle = IPC_GET_ARG1(*call);
    213         sysarg_t match_count = IPC_GET_ARG2(*call);
     210static void devman_add_function(ipc_callid_t callid, ipc_call_t *call)
     211{
     212        fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call);
     213        devman_handle_t dev_handle = IPC_GET_ARG2(*call);
     214        sysarg_t match_count = IPC_GET_ARG3(*call);
    214215        dev_tree_t *tree = &device_tree;
    215216       
    216217        fibril_rwlock_write_lock(&tree->rwlock);
    217         dev_node_t *pdev = find_dev_node_no_lock(&device_tree, parent_handle);
     218
     219        dev_node_t *dev = NULL;
     220        dev_node_t *pdev = find_dev_node_no_lock(&device_tree, dev_handle);
    218221       
    219222        if (pdev == NULL) {
    220223                fibril_rwlock_write_unlock(&tree->rwlock);
    221224                async_answer_0(callid, ENOENT);
     225                return;
     226        }
     227       
     228        if (ftype != fun_inner && ftype != fun_exposed) {
     229                /* Unknown function type */
     230                printf(NAME ": Error, unknown function type provided by driver!\n");
     231
     232                fibril_rwlock_write_unlock(&tree->rwlock);
     233                async_answer_0(callid, EINVAL);
    222234                return;
    223235        }
     
    239251        }
    240252
    241         dev_node_t *dev;
    242 
    243         dev = create_dev_node();
    244         if (dev == NULL) {
    245                 fibril_rwlock_write_unlock(&tree->rwlock);
    246                 delete_fun_node(fun);
    247                 async_answer_0(callid, ENOMEM);
    248                 return;
    249         }
    250 
    251         insert_dev_node(tree, dev, fun);
     253        if (ftype == fun_inner) {
     254                dev = create_dev_node();
     255                if (dev == NULL) {
     256                        fibril_rwlock_write_unlock(&tree->rwlock);
     257                        delete_fun_node(fun);
     258                        async_answer_0(callid, ENOMEM);
     259                        return;
     260                }
     261
     262                insert_dev_node(tree, dev, fun);
     263        }
    252264
    253265        fibril_rwlock_write_unlock(&tree->rwlock);
    254266       
    255         printf(NAME ": devman_add_child %s\n", fun->pathname);
     267        printf(NAME ": devman_add_function %s\n", fun->pathname);
    256268       
    257269        devman_receive_match_ids(match_count, &fun->match_ids);
    258270
    259         /*
    260          * Try to find a suitable driver and assign it to the device.  We do
    261          * not want to block the current fibril that is used for processing
    262          * incoming calls: we will launch a separate fibril to handle the
    263          * driver assigning. That is because assign_driver can actually include
    264          * task spawning which could take some time.
    265          */
    266         fid_t assign_fibril = fibril_create(assign_driver_fibril, dev);
    267         if (assign_fibril == 0) {
     271        if (ftype == fun_inner) {
     272                assert(dev != NULL);
    268273                /*
    269                  * Fallback in case we are out of memory.
    270                  * Probably not needed as we will die soon anyway ;-).
     274                 * Try to find a suitable driver and assign it to the device.  We do
     275                 * not want to block the current fibril that is used for processing
     276                 * incoming calls: we will launch a separate fibril to handle the
     277                 * driver assigning. That is because assign_driver can actually include
     278                 * task spawning which could take some time.
    271279                 */
    272                 (void) assign_driver_fibril(fun);
     280                fid_t assign_fibril = fibril_create(assign_driver_fibril, dev);
     281                if (assign_fibril == 0) {
     282                        /*
     283                         * Fallback in case we are out of memory.
     284                         * Probably not needed as we will die soon anyway ;-).
     285                         */
     286                        (void) assign_driver_fibril(fun);
     287                } else {
     288                        fibril_add_ready(assign_fibril);
     289                }
    273290        } else {
    274                 fibril_add_ready(assign_fibril);
    275         }
    276 
     291                devmap_register_tree_function(fun, tree);
     292        }
     293       
    277294        /* Return device handle to parent's driver. */
    278295        async_answer_1(callid, EOK, fun->handle);
     
    384401                        cont = false;
    385402                        continue;
    386                 case DEVMAN_ADD_CHILD_DEVICE:
    387                         devman_add_child(callid, &call);
     403                case DEVMAN_ADD_FUNCTION:
     404                        devman_add_function(callid, &call);
    388405                        break;
    389406                case DEVMAN_ADD_DEVICE_TO_CLASS:
     
    409426        }
    410427       
    411         fun_node_t * fun = find_fun_node_by_path(&device_tree, pathname);
     428        fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname);
    412429       
    413430        free(pathname);
     
    417434                return;
    418435        }
    419        
     436
    420437        async_answer_1(iid, EOK, fun->handle);
    421438}
     
    450467{
    451468        devman_handle_t handle = IPC_GET_ARG2(*icall);
    452        
    453         fun_node_t *fun = find_fun_node(&device_tree, handle);
    454         if (fun == NULL) {
    455                 printf(NAME ": devman_forward error - no device function with "
     469        devman_handle_t fwd_h;
     470        fun_node_t *fun = NULL;
     471        dev_node_t *dev = NULL;
     472       
     473        fun = find_fun_node(&device_tree, handle);
     474        if (fun == NULL)
     475                dev = find_dev_node(&device_tree, handle);
     476        else
     477                dev = fun->dev;
     478
     479        if (fun == NULL && dev == NULL) {
     480                printf(NAME ": devman_forward error - no device or function with "
    456481                    "handle %" PRIun " was found.\n", handle);
    457482                async_answer_0(iid, ENOENT);
    458483                return;
    459484        }
     485
     486        if (fun == NULL && !drv_to_parent) {
     487                printf(NAME ": devman_forward error - cannot connect to "
     488                    "handle %d, refers to a device.\n", handle);
     489                async_answer_0(iid, ENOENT);
     490                return;
     491        }
    460492       
    461493        driver_t *driver = NULL;
    462494       
    463495        if (drv_to_parent) {
    464                 if (fun->dev->pfun != NULL)
    465                         driver = fun->dev->pfun->dev->drv;
    466         } else if (fun->dev->state == DEVICE_USABLE) {
    467                 driver = fun->dev->drv;
     496                /* Connect to parent function of a device (or device function). */
     497                if (dev->pfun->dev != NULL)
     498                        driver = dev->pfun->dev->drv;
     499                fwd_h = dev->pfun->handle;
     500        } else if (dev->state == DEVICE_USABLE) {
     501                /* Connect to the specified function */
     502                driver = dev->drv;
    468503                assert(driver != NULL);
     504
     505                fwd_h = handle;
    469506        }
    470507       
     
    490527        }
    491528
    492         printf(NAME ": devman_forward: forward connection to function %s to "
    493             "driver %s.\n", fun->pathname, driver->name);
    494         async_forward_fast(iid, driver->phone, method, fun->handle, 0, IPC_FF_NONE);
     529        if (fun != NULL) {
     530                printf(NAME ": devman_forward: forward connection to function %s to "
     531                    "driver %s.\n", fun->pathname, driver->name);
     532        } else {
     533                printf(NAME ": devman_forward: forward connection to device %s to "
     534                    "driver %s.\n", dev->pfun->pathname, driver->name);
     535        }
     536
     537        async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE);
    495538}
    496539
Note: See TracChangeset for help on using the changeset viewer.