Changes in uspace/drv/isa/isa.c [28a3e74:032e0bb] in mainline


Ignore:
File:
1 edited

Legend:

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

    r28a3e74 r032e0bb  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2011 Jiri Svoboda
    43 * All rights reserved.
    54 *
     
    4443#include <stdlib.h>
    4544#include <str.h>
    46 #include <str_error.h>
    4745#include <ctype.h>
    4846#include <macros.h>
     
    5250#include <sys/stat.h>
    5351
    54 #include <ddf/driver.h>
    55 #include <ddf/log.h>
    56 #include <ops/hw_res.h>
     52#include <driver.h>
     53#include <resource.h>
    5754
    5855#include <devman.h>
     
    6158
    6259#define NAME "isa"
    63 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
    64 
    65 /** Obtain soft-state pointer from function node pointer */
    66 #define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data))
     60#define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev"
    6761
    6862#define ISA_MAX_HW_RES 4
    6963
    70 typedef struct isa_fun {
    71         ddf_fun_t *fnode;
     64typedef struct isa_child_data {
    7265        hw_resource_list_t hw_resources;
    73 } isa_fun_t;
    74 
    75 static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
    76 {
    77         isa_fun_t *fun = ISA_FUN(fnode);
    78         assert(fun != NULL);
    79 
    80         return &fun->hw_resources;
    81 }
    82 
    83 static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
    84 {
    85         /* TODO */
     66} isa_child_data_t;
     67
     68static 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
     79static bool isa_enable_child_interrupt(device_t *dev)
     80{
     81        // TODO
    8682
    8783        return false;
    8884}
    8985
    90 static hw_res_ops_t isa_fun_hw_res_ops = {
    91         &isa_get_fun_resources,
    92         &isa_enable_fun_interrupt
     86static resource_iface_t isa_child_res_iface = {
     87        &isa_get_child_resources,
     88        &isa_enable_child_interrupt
    9389};
    9490
    95 static ddf_dev_ops_t isa_fun_ops;
    96 
    97 static int isa_add_device(ddf_dev_t *dev);
     91static device_ops_t isa_child_dev_ops;
     92
     93static int isa_add_device(device_t *dev);
    9894
    9995/** The isa device driver's standard operations */
     
    108104};
    109105
    110 static isa_fun_t *isa_fun_create(ddf_dev_t *dev, const char *name)
    111 {
    112         isa_fun_t *fun = calloc(1, sizeof(isa_fun_t));
    113         if (fun == NULL)
     106
     107static 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
     118static device_t *create_isa_child_dev()
     119{
     120        device_t *dev = create_device();
     121        if (dev == NULL)
    114122                return NULL;
    115123
    116         ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);
    117         if (fnode == NULL) {
    118                 free(fun);
     124        isa_child_data_t *data = create_isa_child_data();
     125        if (data == NULL) {
     126                delete_device(dev);
    119127                return NULL;
    120128        }
    121129
    122         fun->fnode = fnode;
    123         fnode->driver_data = fun;
    124         return fun;
    125 }
    126 
    127 static char *fun_conf_read(const char *conf_path)
     130        dev->driver_data = data;
     131        return dev;
     132}
     133
     134static char *read_dev_conf(const char *conf_path)
    128135{
    129136        bool suc = false;
     
    135142        fd = open(conf_path, O_RDONLY);
    136143        if (fd < 0) {
    137                 ddf_msg(LVL_ERROR, "Unable to open %s", conf_path);
     144                printf(NAME ": unable to open %s\n", conf_path);
    138145                goto cleanup;
    139146        }
     
    142149
    143150        len = lseek(fd, 0, SEEK_END);
    144         lseek(fd, 0, SEEK_SET);
     151        lseek(fd, 0, SEEK_SET); 
    145152        if (len == 0) {
    146                 ddf_msg(LVL_ERROR, "Configuration file '%s' is empty.",
    147                     conf_path);
     153                printf(NAME ": read_dev_conf error: configuration file '%s' "
     154                    "is empty.\n", conf_path);
    148155                goto cleanup;
    149156        }
     
    151158        buf = malloc(len + 1);
    152159        if (buf == NULL) {
    153                 ddf_msg(LVL_ERROR, "Memory allocation failed.");
     160                printf(NAME ": read_dev_conf error: memory allocation failed.\n");
    154161                goto cleanup;
    155162        }
    156163
    157164        if (0 >= read(fd, buf, len)) {
    158                 ddf_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path);
     165                printf(NAME ": read_dev_conf error: unable to read file '%s'.\n",
     166                    conf_path);
    159167                goto cleanup;
    160168        }
     
    241249}
    242250
    243 static 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;
     251static 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;
    247257
    248258        if (count < ISA_MAX_HW_RES) {
     
    250260                resources[count].res.interrupt.irq = irq;
    251261
    252                 fun->hw_resources.count++;
    253 
    254                 ddf_msg(LVL_NOTE, "Added irq 0x%x to function %s", irq,
    255                     fun->fnode->name);
    256         }
    257 }
    258 
    259 static 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;
     262                data->hw_resources.count++;
     263
     264                printf(NAME ": added irq 0x%x to device %s\n", irq, dev->name);
     265        }
     266}
     267
     268static 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;
    263274
    264275        if (count < ISA_MAX_HW_RES) {
     
    268279                resources[count].res.io_range.endianness = LITTLE_ENDIAN;
    269280
    270                 fun->hw_resources.count++;
    271 
    272                 ddf_msg(LVL_NOTE, "Added io range (addr=0x%x, size=0x%x) to "
    273                     "function %s", (unsigned int) addr, (unsigned int) len,
    274                     fun->fnode->name);
    275         }
    276 }
    277 
    278 static void fun_parse_irq(isa_fun_t *fun, char *val)
     281                data->hw_resources.count++;
     282
     283                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
     284                    "device %s\n", addr, len, dev->name);
     285        }
     286}
     287
     288static void get_dev_irq(device_t *dev, char *val)
    279289{
    280290        int irq = 0;
    281291        char *end = NULL;
    282292
    283         val = skip_spaces(val);
     293        val = skip_spaces(val); 
    284294        irq = (int)strtol(val, &end, 0x10);
    285295
    286296        if (val != end)
    287                 isa_fun_set_irq(fun, irq);
    288 }
    289 
    290 static void fun_parse_io_range(isa_fun_t *fun, char *val)
     297                isa_child_set_irq(dev, irq);
     298}
     299
     300static void get_dev_io_range(device_t *dev, char *val)
    291301{
    292302        size_t addr, len;
    293303        char *end = NULL;
    294304
    295         val = skip_spaces(val);
     305        val = skip_spaces(val); 
    296306        addr = strtol(val, &end, 0x10);
    297307
     
    299309                return;
    300310
    301         val = skip_spaces(end);
     311        val = skip_spaces(end); 
    302312        len = strtol(val, &end, 0x10);
    303313
     
    305315                return;
    306316
    307         isa_fun_set_io_range(fun, addr, len);
     317        isa_child_set_io_range(dev, addr, len);
    308318}
    309319
     
    320330}
    321331
    322 static void fun_parse_match_id(isa_fun_t *fun, char *val)
     332static void get_dev_match_id(device_t *dev, char *val)
    323333{
    324334        char *id = NULL;
    325335        int score = 0;
    326336        char *end = NULL;
    327         int rc;
    328 
    329         val = skip_spaces(val);
     337
     338        val = skip_spaces(val);
    330339
    331340        score = (int)strtol(val, &end, 10);
    332341        if (val == end) {
    333                 ddf_msg(LVL_ERROR, "Cannot read match score for function "
    334                     "%s.", fun->fnode->name);
     342                printf(NAME " : error - could not read match score for "
     343                    "device %s.\n", dev->name);
    335344                return;
    336345        }
    337346
    338         val = skip_spaces(end);
     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);
    339355        get_match_id(&id, val);
    340356        if (id == NULL) {
    341                 ddf_msg(LVL_ERROR, "Cannot read match ID for function %s.",
    342                     fun->fnode->name);
     357                printf(NAME " : error - could not read match id for "
     358                    "device %s.\n", dev->name);
     359                delete_match_id(match_id);
    343360                return;
    344361        }
    345362
    346         ddf_msg(LVL_DEBUG, "Adding match id '%s' with score %d to "
    347             "function %s", id, score, fun->fnode->name);
    348 
    349         rc = ddf_fun_add_match_id(fun->fnode, id, score);
    350         if (rc != EOK) {
    351                 ddf_msg(LVL_ERROR, "Failed adding match ID: %s",
    352                     str_error(rc));
    353         }
    354 }
    355 
    356 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
    357     void (*read_fn)(isa_fun_t *, char *))
     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
     371static bool read_dev_prop(device_t *dev, char *line, const char *prop,
     372    void (*read_fn)(device_t *, char *))
    358373{
    359374        size_t proplen = str_size(prop);
     
    362377                line += proplen;
    363378                line = skip_spaces(line);
    364                 (*read_fn)(fun, line);
     379                (*read_fn)(dev, line);
    365380
    366381                return true;
     
    370385}
    371386
    372 static void fun_prop_parse(isa_fun_t *fun, char *line)
     387static void get_dev_prop(device_t *dev, char *line)
    373388{
    374389        /* Skip leading spaces. */
    375390        line = skip_spaces(line);
    376391
    377         if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) &&
    378             !prop_parse(fun, line, "irq", &fun_parse_irq) &&
    379             !prop_parse(fun, line, "match", &fun_parse_match_id)) {
    380 
    381                 ddf_msg(LVL_ERROR, "Undefined device property at line '%s'",
    382                     line);
    383         }
    384 }
    385 
    386 static void fun_hw_res_alloc(isa_fun_t *fun)
    387 {
    388         fun->hw_resources.resources =
     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))
     395        {
     396            printf(NAME " error undefined device property at line '%s'\n",
     397                line);
     398        }
     399}
     400
     401static 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 =
    389405            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    390406}
    391407
    392 static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev)
     408static char *read_isa_dev_info(char *dev_conf, device_t *parent)
    393409{
    394410        char *line;
    395         char *fun_name = NULL;
     411        char *dev_name = NULL;
    396412
    397413        /* Skip empty lines. */
    398414        while (true) {
    399                 line = str_get_line(fun_conf, &fun_conf);
     415                line = str_get_line(dev_conf, &dev_conf);
    400416
    401417                if (line == NULL) {
     
    409425
    410426        /* Get device name. */
    411         fun_name = get_device_name(line);
    412         if (fun_name == NULL)
     427        dev_name = get_device_name(line);
     428        if (dev_name == NULL)
    413429                return NULL;
    414430
    415         isa_fun_t *fun = isa_fun_create(dev, fun_name);
    416         if (fun == NULL) {
    417                 free(fun_name);
     431        device_t *dev = create_isa_child_dev();
     432        if (dev == NULL) {
     433                free(dev_name);
    418434                return NULL;
    419435        }
    420436
     437        dev->name = dev_name;
     438
    421439        /* Allocate buffer for the list of hardware resources of the device. */
    422         fun_hw_res_alloc(fun);
     440        child_alloc_hw_res(dev);
    423441
    424442        /* Get properties of the device (match ids, irq and io range). */
    425443        while (true) {
    426                 line = str_get_line(fun_conf, &fun_conf);
     444                line = str_get_line(dev_conf, &dev_conf);
    427445
    428446                if (line_empty(line)) {
     
    435453                 * and store it in the device structure.
    436454                 */
    437                 fun_prop_parse(fun, line);
     455                get_dev_prop(dev, line);
     456
     457                //printf(NAME ": next line ='%s'\n", dev_conf);
     458                //printf(NAME ": current line ='%s'\n", line);
    438459        }
    439460
    440461        /* Set device operations to the device. */
    441         fun->fnode->ops = &isa_fun_ops;
    442 
    443         ddf_msg(LVL_DEBUG, "Binding function %s.", fun->fnode->name);
    444 
    445         /* XXX Handle error */
    446         (void) ddf_fun_bind(fun->fnode);
    447 
    448         return fun_conf;
    449 }
    450 
    451 static void fun_conf_parse(char *conf, ddf_dev_t *dev)
     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
     471static void parse_dev_conf(char *conf, device_t *parent)
    452472{
    453473        while (conf != NULL && *conf != '\0') {
    454                 conf = isa_fun_read_info(conf, dev);
    455         }
    456 }
    457 
    458 static void isa_functions_add(ddf_dev_t *dev)
    459 {
    460         char *fun_conf;
    461 
    462         fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
    463         if (fun_conf != NULL) {
    464                 fun_conf_parse(fun_conf, dev);
    465                 free(fun_conf);
    466         }
    467 }
    468 
    469 static int isa_add_device(ddf_dev_t *dev)
    470 {
    471         ddf_msg(LVL_DEBUG, "isa_add_device, device handle = %d",
    472             (int) dev->handle);
    473 
    474         /* Make the bus device more visible. Does not do anything. */
    475         ddf_msg(LVL_DEBUG, "Adding a 'ctl' function");
    476 
    477         ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl");
    478         if (ctl == NULL) {
    479                 ddf_msg(LVL_ERROR, "Failed creating control function.");
    480                 return EXDEV;
    481         }
    482 
    483         if (ddf_fun_bind(ctl) != EOK) {
    484                 ddf_msg(LVL_ERROR, "Failed binding control function.");
    485                 return EXDEV;
    486         }
    487 
    488         /* Add functions as specified in the configuration file. */
    489         isa_functions_add(dev);
    490         ddf_msg(LVL_NOTE, "Finished enumerating legacy functions");
     474                conf = read_isa_dev_info(conf, parent);
     475        }
     476}
     477
     478static 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
     489static 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",
     496            dev->handle);
    491497
    492498        return EOK;
     
    495501static void isa_init()
    496502{
    497         ddf_log_init(NAME, LVL_ERROR);
    498         isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
     503        isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_res_iface;
    499504}
    500505
     
    503508        printf(NAME ": HelenOS ISA bus driver\n");
    504509        isa_init();
    505         return ddf_driver_main(&isa_driver);
     510        return driver_main(&isa_driver);
    506511}
    507512
     
    509514 * @}
    510515 */
     516 
Note: See TracChangeset for help on using the changeset viewer.