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


Ignore:
File:
1 edited

Legend:

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

    raf6b5157 r7e752b2  
    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 <ops/hw_res.h>
     52#include <driver.h>
     53#include <resource.h>
    5654
    5755#include <devman.h>
     
    6058
    6159#define NAME "isa"
    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))
     60#define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev"
    6661
    6762#define ISA_MAX_HW_RES 4
    6863
    69 typedef struct isa_fun {
    70         ddf_fun_t *fnode;
     64typedef struct isa_child_data {
    7165        hw_resource_list_t hw_resources;
    72 } isa_fun_t;
    73 
    74 static 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 
    82 static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
     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)
    8380{
    8481        // TODO
     
    8784}
    8885
    89 static hw_res_ops_t isa_fun_hw_res_ops = {
    90         &isa_get_fun_resources,
    91         &isa_enable_fun_interrupt
     86static resource_iface_t isa_child_res_iface = {
     87        &isa_get_child_resources,
     88        &isa_enable_child_interrupt
    9289};
    9390
    94 static ddf_dev_ops_t isa_fun_ops;
    95 
    96 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);
    9794
    9895/** The isa device driver's standard operations */
     
    107104};
    108105
    109 static 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)
     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)
    113122                return NULL;
    114123
    115         ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);
    116         if (fnode == NULL) {
    117                 free(fun);
     124        isa_child_data_t *data = create_isa_child_data();
     125        if (data == NULL) {
     126                delete_device(dev);
    118127                return NULL;
    119128        }
    120129
    121         fun->fnode = fnode;
    122         fnode->driver_data = fun;
    123         return fun;
    124 }
    125 
    126 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)
    127135{
    128136        bool suc = false;
     
    143151        lseek(fd, 0, SEEK_SET);
    144152        if (len == 0) {
    145                 printf(NAME ": fun_conf_read error: configuration file '%s' "
     153                printf(NAME ": read_dev_conf error: configuration file '%s' "
    146154                    "is empty.\n", conf_path);
    147155                goto cleanup;
     
    150158        buf = malloc(len + 1);
    151159        if (buf == NULL) {
    152                 printf(NAME ": fun_conf_read error: memory allocation failed.\n");
     160                printf(NAME ": read_dev_conf error: memory allocation failed.\n");
    153161                goto cleanup;
    154162        }
    155163
    156164        if (0 >= read(fd, buf, len)) {
    157                 printf(NAME ": fun_conf_read error: unable to read file '%s'.\n",
     165                printf(NAME ": read_dev_conf error: unable to read file '%s'.\n",
    158166                    conf_path);
    159167                goto cleanup;
     
    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                 printf(NAME ": added irq 0x%x to function %s\n", 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++;
     281                data->hw_resources.count++;
    271282
    272283                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
    273                     "function %s\n", (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)
     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) {
    333342                printf(NAME " : error - could not read match score for "
    334                     "function %s.\n", fun->fnode->name);
     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) {
    341357                printf(NAME " : error - could not read match id for "
    342                     "function %s.\n", fun->fnode->name);
     358                    "device %s.\n", dev->name);
     359                delete_match_id(match_id);
    343360                return;
    344361        }
    345362
    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 
    354 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
    355     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 *))
    356373{
    357374        size_t proplen = str_size(prop);
     
    360377                line += proplen;
    361378                line = skip_spaces(line);
    362                 (*read_fn)(fun, line);
     379                (*read_fn)(dev, line);
    363380
    364381                return true;
     
    368385}
    369386
    370 static void fun_prop_parse(isa_fun_t *fun, char *line)
     387static void get_dev_prop(device_t *dev, char *line)
    371388{
    372389        /* Skip leading spaces. */
    373390        line = skip_spaces(line);
    374391
    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))
     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))
    378395        {
    379396            printf(NAME " error undefined device property at line '%s'\n",
     
    382399}
    383400
    384 static void fun_hw_res_alloc(isa_fun_t *fun)
    385 {
    386         fun->hw_resources.resources =
     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 =
    387405            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    388406}
    389407
    390 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)
    391409{
    392410        char *line;
    393         char *fun_name = NULL;
     411        char *dev_name = NULL;
    394412
    395413        /* Skip empty lines. */
    396414        while (true) {
    397                 line = str_get_line(fun_conf, &fun_conf);
     415                line = str_get_line(dev_conf, &dev_conf);
    398416
    399417                if (line == NULL) {
     
    407425
    408426        /* Get device name. */
    409         fun_name = get_device_name(line);
    410         if (fun_name == NULL)
     427        dev_name = get_device_name(line);
     428        if (dev_name == NULL)
    411429                return NULL;
    412430
    413         isa_fun_t *fun = isa_fun_create(dev, fun_name);
    414         if (fun == NULL) {
    415                 free(fun_name);
     431        device_t *dev = create_isa_child_dev();
     432        if (dev == NULL) {
     433                free(dev_name);
    416434                return NULL;
    417435        }
    418436
     437        dev->name = dev_name;
     438
    419439        /* Allocate buffer for the list of hardware resources of the device. */
    420         fun_hw_res_alloc(fun);
     440        child_alloc_hw_res(dev);
    421441
    422442        /* Get properties of the device (match ids, irq and io range). */
    423443        while (true) {
    424                 line = str_get_line(fun_conf, &fun_conf);
     444                line = str_get_line(dev_conf, &dev_conf);
    425445
    426446                if (line_empty(line)) {
     
    433453                 * and store it in the device structure.
    434454                 */
    435                 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);
    436459        }
    437460
    438461        /* Set device operations to the device. */
    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 
    449 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)
    450472{
    451473        while (conf != NULL && *conf != '\0') {
    452                 conf = isa_fun_read_info(conf, dev);
    453         }
    454 }
    455 
    456 static 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 
    467 static 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");
     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");
    489496
    490497        return EOK;
     
    493500static void isa_init()
    494501{
    495         isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
     502        isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_res_iface;
    496503}
    497504
     
    500507        printf(NAME ": HelenOS ISA bus driver\n");
    501508        isa_init();
    502         return ddf_driver_main(&isa_driver);
     509        return driver_main(&isa_driver);
    503510}
    504511
     
    506513 * @}
    507514 */
     515 
Note: See TracChangeset for help on using the changeset viewer.