Changes in uspace/drv/isa/isa.c [7e752b2:af6b5157] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/isa/isa.c

    r7e752b2 raf6b5157  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4344#include <stdlib.h>
    4445#include <str.h>
     46#include <str_error.h>
    4547#include <ctype.h>
    4648#include <macros.h>
     
    5052#include <sys/stat.h>
    5153
    52 #include <driver.h>
    53 #include <resource.h>
     54#include <ddf/driver.h>
     55#include <ops/hw_res.h>
    5456
    5557#include <devman.h>
     
    5860
    5961#define NAME "isa"
    60 #define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev"
     62#define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
     63
     64/** Obtain soft-state pointer from function node pointer */
     65#define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data))
    6166
    6267#define ISA_MAX_HW_RES 4
    6368
    64 typedef struct isa_child_data {
     69typedef struct isa_fun {
     70        ddf_fun_t *fnode;
    6571        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)
    74                 return NULL;
    75 
    76         return &dev_data->hw_resources;
    77 }
    78 
    79 static bool isa_enable_child_interrupt(device_t *dev)
     72} isa_fun_t;
     73
     74static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
     75{
     76        isa_fun_t *fun = ISA_FUN(fnode);
     77        assert(fun != NULL);
     78
     79        return &fun->hw_resources;
     80}
     81
     82static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
    8083{
    8184        // TODO
     
    8487}
    8588
    86 static resource_iface_t isa_child_res_iface = {
    87         &isa_get_child_resources,
    88         &isa_enable_child_interrupt
     89static hw_res_ops_t isa_fun_hw_res_ops = {
     90        &isa_get_fun_resources,
     91        &isa_enable_fun_interrupt
    8992};
    9093
    91 static device_ops_t isa_child_dev_ops;
    92 
    93 static int isa_add_device(device_t *dev);
     94static ddf_dev_ops_t isa_fun_ops;
     95
     96static int isa_add_device(ddf_dev_t *dev);
    9497
    9598/** The isa device driver's standard operations */
     
    104107};
    105108
    106 
    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));
    112         if (data != NULL)
    113                 memset(data, 0, sizeof(isa_child_data_t));
    114 
    115         return data;
    116 }
    117 
    118 static device_t *create_isa_child_dev()
    119 {
    120         device_t *dev = create_device();
    121         if (dev == NULL)
     109static isa_fun_t *isa_fun_create(ddf_dev_t *dev, const char *name)
     110{
     111        isa_fun_t *fun = calloc(1, sizeof(isa_fun_t));
     112        if (fun == NULL)
    122113                return NULL;
    123114
    124         isa_child_data_t *data = create_isa_child_data();
    125         if (data == NULL) {
    126                 delete_device(dev);
     115        ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);
     116        if (fnode == NULL) {
     117                free(fun);
    127118                return NULL;
    128119        }
    129120
    130         dev->driver_data = data;
    131         return dev;
    132 }
    133 
    134 static char *read_dev_conf(const char *conf_path)
     121        fun->fnode = fnode;
     122        fnode->driver_data = fun;
     123        return fun;
     124}
     125
     126static char *fun_conf_read(const char *conf_path)
    135127{
    136128        bool suc = false;
     
    151143        lseek(fd, 0, SEEK_SET);
    152144        if (len == 0) {
    153                 printf(NAME ": read_dev_conf error: configuration file '%s' "
     145                printf(NAME ": fun_conf_read error: configuration file '%s' "
    154146                    "is empty.\n", conf_path);
    155147                goto cleanup;
     
    158150        buf = malloc(len + 1);
    159151        if (buf == NULL) {
    160                 printf(NAME ": read_dev_conf error: memory allocation failed.\n");
     152                printf(NAME ": fun_conf_read error: memory allocation failed.\n");
    161153                goto cleanup;
    162154        }
    163155
    164156        if (0 >= read(fd, buf, len)) {
    165                 printf(NAME ": read_dev_conf error: unable to read file '%s'.\n",
     157                printf(NAME ": fun_conf_read error: unable to read file '%s'.\n",
    166158                    conf_path);
    167159                goto cleanup;
     
    249241}
    250242
    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;
    254 
    255         size_t count = data->hw_resources.count;
    256         hw_resource_t *resources = data->hw_resources.resources;
     243static void isa_fun_set_irq(isa_fun_t *fun, int irq)
     244{
     245        size_t count = fun->hw_resources.count;
     246        hw_resource_t *resources = fun->hw_resources.resources;
    257247
    258248        if (count < ISA_MAX_HW_RES) {
     
    260250                resources[count].res.interrupt.irq = irq;
    261251
    262                 data->hw_resources.count++;
    263 
    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;
    271 
    272         size_t count = data->hw_resources.count;
    273         hw_resource_t *resources = data->hw_resources.resources;
     252                fun->hw_resources.count++;
     253
     254                printf(NAME ": added irq 0x%x to function %s\n", irq,
     255                    fun->fnode->name);
     256        }
     257}
     258
     259static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
     260{
     261        size_t count = fun->hw_resources.count;
     262        hw_resource_t *resources = fun->hw_resources.resources;
    274263
    275264        if (count < ISA_MAX_HW_RES) {
     
    279268                resources[count].res.io_range.endianness = LITTLE_ENDIAN;
    280269
    281                 data->hw_resources.count++;
     270                fun->hw_resources.count++;
    282271
    283272                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
    284                     "device %s\n", addr, len, dev->name);
    285         }
    286 }
    287 
    288 static void get_dev_irq(device_t *dev, char *val)
     273                    "function %s\n", (unsigned int) addr, (unsigned int) len,
     274                    fun->fnode->name);
     275        }
     276}
     277
     278static void fun_parse_irq(isa_fun_t *fun, char *val)
    289279{
    290280        int irq = 0;
    291281        char *end = NULL;
    292282
    293         val = skip_spaces(val); 
     283        val = skip_spaces(val);
    294284        irq = (int)strtol(val, &end, 0x10);
    295285
    296286        if (val != end)
    297                 isa_child_set_irq(dev, irq);
    298 }
    299 
    300 static void get_dev_io_range(device_t *dev, char *val)
     287                isa_fun_set_irq(fun, irq);
     288}
     289
     290static void fun_parse_io_range(isa_fun_t *fun, char *val)
    301291{
    302292        size_t addr, len;
    303293        char *end = NULL;
    304294
    305         val = skip_spaces(val); 
     295        val = skip_spaces(val);
    306296        addr = strtol(val, &end, 0x10);
    307297
     
    309299                return;
    310300
    311         val = skip_spaces(end); 
     301        val = skip_spaces(end);
    312302        len = strtol(val, &end, 0x10);
    313303
     
    315305                return;
    316306
    317         isa_child_set_io_range(dev, addr, len);
     307        isa_fun_set_io_range(fun, addr, len);
    318308}
    319309
     
    330320}
    331321
    332 static void get_dev_match_id(device_t *dev, char *val)
     322static void fun_parse_match_id(isa_fun_t *fun, char *val)
    333323{
    334324        char *id = NULL;
    335325        int score = 0;
    336326        char *end = NULL;
    337 
    338         val = skip_spaces(val);
     327        int rc;
     328
     329        val = skip_spaces(val);
    339330
    340331        score = (int)strtol(val, &end, 10);
    341332        if (val == end) {
    342333                printf(NAME " : error - could not read match score for "
    343                     "device %s.\n", dev->name);
     334                    "function %s.\n", fun->fnode->name);
    344335                return;
    345336        }
    346337
    347         match_id_t *match_id = create_match_id();
    348         if (match_id == NULL) {
    349                 printf(NAME " : failed to allocate match id for device %s.\n",
    350                     dev->name);
    351                 return;
    352         }
    353 
    354         val = skip_spaces(end);
     338        val = skip_spaces(end);
    355339        get_match_id(&id, val);
    356340        if (id == NULL) {
    357341                printf(NAME " : error - could not read match id for "
    358                     "device %s.\n", dev->name);
    359                 delete_match_id(match_id);
     342                    "function %s.\n", fun->fnode->name);
    360343                return;
    361344        }
    362345
    363         match_id->id = id;
    364         match_id->score = score;
    365 
    366         printf(NAME ": adding match id '%s' with score %d to device %s\n", id,
    367             score, dev->name);
    368         add_match_id(&dev->match_ids, match_id);
    369 }
    370 
    371 static bool read_dev_prop(device_t *dev, char *line, const char *prop,
    372     void (*read_fn)(device_t *, char *))
     346        printf(NAME ": adding match id '%s' with score %d to function %s\n", id,
     347            score, fun->fnode->name);
     348
     349        rc = ddf_fun_add_match_id(fun->fnode, id, score);
     350        if (rc != EOK)
     351                printf(NAME ": error adding match ID: %s\n", str_error(rc));
     352}
     353
     354static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
     355    void (*read_fn)(isa_fun_t *, char *))
    373356{
    374357        size_t proplen = str_size(prop);
     
    377360                line += proplen;
    378361                line = skip_spaces(line);
    379                 (*read_fn)(dev, line);
     362                (*read_fn)(fun, line);
    380363
    381364                return true;
     
    385368}
    386369
    387 static void get_dev_prop(device_t *dev, char *line)
     370static void fun_prop_parse(isa_fun_t *fun, char *line)
    388371{
    389372        /* Skip leading spaces. */
    390373        line = skip_spaces(line);
    391374
    392         if (!read_dev_prop(dev, line, "io_range", &get_dev_io_range) &&
    393             !read_dev_prop(dev, line, "irq", &get_dev_irq) &&
    394             !read_dev_prop(dev, line, "match", &get_dev_match_id))
     375        if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) &&
     376            !prop_parse(fun, line, "irq", &fun_parse_irq) &&
     377            !prop_parse(fun, line, "match", &fun_parse_match_id))
    395378        {
    396379            printf(NAME " error undefined device property at line '%s'\n",
     
    399382}
    400383
    401 static void child_alloc_hw_res(device_t *dev)
    402 {
    403         isa_child_data_t *data = (isa_child_data_t *)dev->driver_data;
    404         data->hw_resources.resources =
     384static void fun_hw_res_alloc(isa_fun_t *fun)
     385{
     386        fun->hw_resources.resources =
    405387            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    406388}
    407389
    408 static char *read_isa_dev_info(char *dev_conf, device_t *parent)
     390static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev)
    409391{
    410392        char *line;
    411         char *dev_name = NULL;
     393        char *fun_name = NULL;
    412394
    413395        /* Skip empty lines. */
    414396        while (true) {
    415                 line = str_get_line(dev_conf, &dev_conf);
     397                line = str_get_line(fun_conf, &fun_conf);
    416398
    417399                if (line == NULL) {
     
    425407
    426408        /* Get device name. */
    427         dev_name = get_device_name(line);
    428         if (dev_name == NULL)
     409        fun_name = get_device_name(line);
     410        if (fun_name == NULL)
    429411                return NULL;
    430412
    431         device_t *dev = create_isa_child_dev();
    432         if (dev == NULL) {
    433                 free(dev_name);
     413        isa_fun_t *fun = isa_fun_create(dev, fun_name);
     414        if (fun == NULL) {
     415                free(fun_name);
    434416                return NULL;
    435417        }
    436418
    437         dev->name = dev_name;
    438 
    439419        /* Allocate buffer for the list of hardware resources of the device. */
    440         child_alloc_hw_res(dev);
     420        fun_hw_res_alloc(fun);
    441421
    442422        /* Get properties of the device (match ids, irq and io range). */
    443423        while (true) {
    444                 line = str_get_line(dev_conf, &dev_conf);
     424                line = str_get_line(fun_conf, &fun_conf);
    445425
    446426                if (line_empty(line)) {
     
    453433                 * and store it in the device structure.
    454434                 */
    455                 get_dev_prop(dev, line);
    456 
    457                 //printf(NAME ": next line ='%s'\n", dev_conf);
    458                 //printf(NAME ": current line ='%s'\n", line);
     435                fun_prop_parse(fun, line);
    459436        }
    460437
    461438        /* Set device operations to the device. */
    462         dev->ops = &isa_child_dev_ops;
    463 
    464         printf(NAME ": child_device_register(dev, parent); device is %s.\n",
    465             dev->name);
    466         child_device_register(dev, parent);
    467 
    468         return dev_conf;
    469 }
    470 
    471 static void parse_dev_conf(char *conf, device_t *parent)
     439        fun->fnode->ops = &isa_fun_ops;
     440
     441        printf(NAME ": Binding function %s.\n", fun->fnode->name);
     442
     443        /* XXX Handle error */
     444        (void) ddf_fun_bind(fun->fnode);
     445
     446        return fun_conf;
     447}
     448
     449static void fun_conf_parse(char *conf, ddf_dev_t *dev)
    472450{
    473451        while (conf != NULL && *conf != '\0') {
    474                 conf = read_isa_dev_info(conf, parent);
    475         }
    476 }
    477 
    478 static void add_legacy_children(device_t *parent)
    479 {
    480         char *dev_conf;
    481 
    482         dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH);
    483         if (dev_conf != NULL) {
    484                 parse_dev_conf(dev_conf, parent);
    485                 free(dev_conf);
    486         }
    487 }
    488 
    489 static int isa_add_device(device_t *dev)
    490 {
    491         printf(NAME ": isa_add_device, device handle = %d\n", dev->handle);
    492 
    493         /* Add child devices. */
    494         add_legacy_children(dev);
    495         printf(NAME ": finished the enumeration of legacy devices\n");
     452                conf = isa_fun_read_info(conf, dev);
     453        }
     454}
     455
     456static void isa_functions_add(ddf_dev_t *dev)
     457{
     458        char *fun_conf;
     459
     460        fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
     461        if (fun_conf != NULL) {
     462                fun_conf_parse(fun_conf, dev);
     463                free(fun_conf);
     464        }
     465}
     466
     467static int isa_add_device(ddf_dev_t *dev)
     468{
     469        printf(NAME ": isa_add_device, device handle = %d\n",
     470            (int) dev->handle);
     471
     472        /* Make the bus device more visible. Does not do anything. */
     473        printf(NAME ": adding a 'ctl' function\n");
     474
     475        ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl");
     476        if (ctl == NULL) {
     477                printf(NAME ": Error creating control function.\n");
     478                return EXDEV;
     479        }
     480
     481        if (ddf_fun_bind(ctl) != EOK) {
     482                printf(NAME ": Error binding control function.\n");
     483                return EXDEV;
     484        }
     485
     486        /* Add functions as specified in the configuration file. */
     487        isa_functions_add(dev);
     488        printf(NAME ": finished the enumeration of legacy functions\n");
    496489
    497490        return EOK;
     
    500493static void isa_init()
    501494{
    502         isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_res_iface;
     495        isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
    503496}
    504497
     
    507500        printf(NAME ": HelenOS ISA bus driver\n");
    508501        isa_init();
    509         return driver_main(&isa_driver);
     502        return ddf_driver_main(&isa_driver);
    510503}
    511504
     
    513506 * @}
    514507 */
    515  
Note: See TracChangeset for help on using the changeset viewer.