Ignore:
File:
1 edited

Legend:

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

    r3869c596 r3e6a98c5  
    4242#include <stdio.h>
    4343#include <errno.h>
    44 #include <bool.h>
     44#include <stdbool.h>
    4545#include <fibril_synch.h>
    4646#include <stdlib.h>
     
    7373#define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
    7474
    75 /** Obtain soft-state from device node */
    76 #define ISA_BUS(dev) ((isa_bus_t *) ((dev)->driver_data))
    77 
    78 /** Obtain soft-state from function node */
    79 #define ISA_FUN(fun) ((isa_fun_t *) ((fun)->driver_data))
    80 
    8175#define ISA_MAX_HW_RES 5
    8276
     
    9185        fibril_mutex_t mutex;
    9286        ddf_fun_t *fnode;
    93         hw_resource_t resources[ISA_MAX_HW_RES];
    9487        hw_resource_list_t hw_resources;
    9588        link_t bus_link;
    9689} isa_fun_t;
    9790
    98 static hw_resource_list_t *isa_fun_get_resources(ddf_fun_t *fnode)
    99 {
    100         isa_fun_t *fun = ISA_FUN(fnode);
    101         assert(fun);
     91/** Obtain soft-state from device node */
     92static isa_bus_t *isa_bus(ddf_dev_t *dev)
     93{
     94        return ddf_dev_data_get(dev);
     95}
     96
     97/** Obtain soft-state from function node */
     98static isa_fun_t *isa_fun(ddf_fun_t *fun)
     99{
     100        return ddf_fun_data_get(fun);
     101}
     102
     103static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
     104{
     105        isa_fun_t *fun = isa_fun(fnode);
     106        assert(fun != NULL);
    102107
    103108        return &fun->hw_resources;
    104109}
    105110
    106 static bool isa_fun_enable_interrupt(ddf_fun_t *fnode)
     111static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
    107112{
    108113        /* This is an old ugly way, copied from pci driver */
    109114        assert(fnode);
    110         isa_fun_t *isa_fun = ISA_FUN(fnode);
     115        isa_fun_t *fun = isa_fun(fnode);
    111116
    112117        sysarg_t apic;
     
    124129                return false;
    125130
    126         assert(isa_fun);
    127         const hw_resource_list_t *res = &isa_fun->hw_resources;
     131        const hw_resource_list_t *res = &fun->hw_resources;
    128132        assert(res);
    129133        for (size_t i = 0; i < res->count; ++i) {
     
    147151}
    148152
    149 static int isa_fun_setup_dma(ddf_fun_t *fnode,
     153static int isa_dma_channel_fun_setup(ddf_fun_t *fnode,
    150154    unsigned int channel, uint32_t pa, uint16_t size, uint8_t mode)
    151155{
    152156        assert(fnode);
    153         isa_fun_t *isa_fun = fnode->driver_data;
    154         assert(isa_fun);
    155         const hw_resource_list_t *res = &isa_fun->hw_resources;
     157        isa_fun_t *fun = isa_fun(fnode);
     158        const hw_resource_list_t *res = &fun->hw_resources;
    156159        assert(res);
    157160       
     161        const unsigned int ch = channel;
    158162        for (size_t i = 0; i < res->count; ++i) {
    159                 /* Check for assigned channel */
    160163                if (((res->resources[i].type == DMA_CHANNEL_16) &&
    161                     (res->resources[i].res.dma_channel.dma16 == channel)) ||
     164                    (res->resources[i].res.dma_channel.dma16 == ch)) ||
    162165                    ((res->resources[i].type == DMA_CHANNEL_8) &&
    163                     (res->resources[i].res.dma_channel.dma8 == channel))) {
    164                         return dma_channel_setup(channel, pa, size, mode);
     166                    (res->resources[i].res.dma_channel.dma8 == ch))) {
     167                        return dma_setup_channel(channel, pa, size, mode);
    165168                }
    166169        }
     
    169172}
    170173
    171 static int isa_fun_remain_dma(ddf_fun_t *fnode,
    172     unsigned channel, size_t *size)
    173 {
    174         assert(size);
    175         assert(fnode);
    176         isa_fun_t *isa_fun = fnode->driver_data;
    177         assert(isa_fun);
    178         const hw_resource_list_t *res = &isa_fun->hw_resources;
    179         assert(res);
    180        
    181         for (size_t i = 0; i < res->count; ++i) {
    182                 /* Check for assigned channel */
    183                 if (((res->resources[i].type == DMA_CHANNEL_16) &&
    184                     (res->resources[i].res.dma_channel.dma16 == channel)) ||
    185                     ((res->resources[i].type == DMA_CHANNEL_8) &&
    186                     (res->resources[i].res.dma_channel.dma8 == channel))) {
    187                         return dma_channel_remain(channel, size);
    188                 }
    189         }
    190        
    191         return EINVAL;
    192 }
    193 
    194174static hw_res_ops_t isa_fun_hw_res_ops = {
    195         .get_resource_list = isa_fun_get_resources,
    196         .enable_interrupt = isa_fun_enable_interrupt,
    197         .dma_channel_setup = isa_fun_setup_dma,
    198         .dma_channel_remain = isa_fun_remain_dma,
     175        .get_resource_list = isa_get_fun_resources,
     176        .enable_interrupt = isa_enable_fun_interrupt,
     177        .dma_channel_setup = isa_dma_channel_fun_setup,
    199178};
    200179
    201 static ddf_dev_ops_t isa_fun_ops= {
    202         .interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops,
    203 };
     180static ddf_dev_ops_t isa_fun_ops;
    204181
    205182static int isa_dev_add(ddf_dev_t *dev);
     
    235212
    236213        fibril_mutex_initialize(&fun->mutex);
    237         fun->hw_resources.resources = fun->resources;
    238 
    239214        fun->fnode = fnode;
    240215        return fun;
     
    295270{
    296271        char *line = str;
    297         *next = NULL;
    298272
    299273        if (str == NULL) {
     274                *next = NULL;
    300275                return NULL;
    301276        }
     
    307282        if (*str != '\0') {
    308283                *next = str + 1;
     284        } else {
     285                *next = NULL;
    309286        }
    310287
     
    333310        /* Get the name part of the rest of the line. */
    334311        strtok(line, ":");
    335         return line;
    336 }
    337 
    338 static inline const char *skip_spaces(const char *line)
     312
     313        /* Allocate output buffer. */
     314        size_t size = str_size(line) + 1;
     315        char *name = malloc(size);
     316
     317        if (name != NULL) {
     318                /* Copy the result to the output buffer. */
     319                str_cpy(name, size, line);
     320        }
     321
     322        return name;
     323}
     324
     325static inline char *skip_spaces(char *line)
    339326{
    340327        /* Skip leading spaces. */
     
    345332}
    346333
    347 static void isa_fun_add_irq(isa_fun_t *fun, int irq)
     334static void isa_fun_set_irq(isa_fun_t *fun, int irq)
    348335{
    349336        size_t count = fun->hw_resources.count;
     
    357344
    358345                ddf_msg(LVL_NOTE, "Added irq 0x%x to function %s", irq,
    359                     fun->fnode->name);
    360         }
    361 }
    362 
    363 static void isa_fun_add_dma(isa_fun_t *fun, int dma)
     346                    ddf_fun_get_name(fun->fnode));
     347        }
     348}
     349
     350static void isa_fun_set_dma(isa_fun_t *fun, int dma)
    364351{
    365352        size_t count = fun->hw_resources.count;
     
    373360                        fun->hw_resources.count++;
    374361                        ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
    375                             fun->fnode->name);
     362                            ddf_fun_get_name(fun->fnode));
    376363                       
    377364                        return;
     
    384371                        fun->hw_resources.count++;
    385372                        ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
    386                             fun->fnode->name);
     373                            ddf_fun_get_name(fun->fnode));
    387374                       
    388375                        return;
     
    390377               
    391378                ddf_msg(LVL_WARN, "Skipped dma 0x%x for function %s", dma,
    392                     fun->fnode->name);
    393         }
    394 }
    395 
    396 static void isa_fun_add_io_range(isa_fun_t *fun, size_t addr, size_t len)
     379                    ddf_fun_get_name(fun->fnode));
     380        }
     381}
     382
     383static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
    397384{
    398385        size_t count = fun->hw_resources.count;
     
    409396                ddf_msg(LVL_NOTE, "Added io range (addr=0x%x, size=0x%x) to "
    410397                    "function %s", (unsigned int) addr, (unsigned int) len,
    411                     fun->fnode->name);
    412         }
    413 }
    414 
    415 static void fun_parse_irq(isa_fun_t *fun, const char *val)
     398                    ddf_fun_get_name(fun->fnode));
     399        }
     400}
     401
     402static void fun_parse_irq(isa_fun_t *fun, char *val)
    416403{
    417404        int irq = 0;
     
    422409
    423410        if (val != end)
    424                 isa_fun_add_irq(fun, irq);
    425 }
    426 
    427 static void fun_parse_dma(isa_fun_t *fun, const char *val)
    428 {
     411                isa_fun_set_irq(fun, irq);
     412}
     413
     414static void fun_parse_dma(isa_fun_t *fun, char *val)
     415{
     416        unsigned int dma = 0;
    429417        char *end = NULL;
    430418       
    431419        val = skip_spaces(val);
    432         const int dma = strtol(val, &end, 10);
     420        dma = (unsigned int) strtol(val, &end, 10);
    433421       
    434422        if (val != end)
    435                 isa_fun_add_dma(fun, dma);
    436 }
    437 
    438 static void fun_parse_io_range(isa_fun_t *fun, const char *val)
     423                isa_fun_set_dma(fun, dma);
     424}
     425
     426static void fun_parse_io_range(isa_fun_t *fun, char *val)
    439427{
    440428        size_t addr, len;
     
    453441                return;
    454442
    455         isa_fun_add_io_range(fun, addr, len);
    456 }
    457 
    458 static void get_match_id(char **id, const char *val)
    459 {
    460         const char *end = val;
     443        isa_fun_set_io_range(fun, addr, len);
     444}
     445
     446static void get_match_id(char **id, char *val)
     447{
     448        char *end = val;
    461449
    462450        while (!isspace(*end))
     
    468456}
    469457
    470 static void fun_parse_match_id(isa_fun_t *fun, const char *val)
     458static void fun_parse_match_id(isa_fun_t *fun, char *val)
    471459{
    472460        char *id = NULL;
     461        int score = 0;
    473462        char *end = NULL;
     463        int rc;
    474464
    475465        val = skip_spaces(val);
    476466
    477         int score = (int)strtol(val, &end, 10);
     467        score = (int)strtol(val, &end, 10);
    478468        if (val == end) {
    479469                ddf_msg(LVL_ERROR, "Cannot read match score for function "
    480                     "%s.", fun->fnode->name);
     470                    "%s.", ddf_fun_get_name(fun->fnode));
    481471                return;
    482472        }
     
    486476        if (id == NULL) {
    487477                ddf_msg(LVL_ERROR, "Cannot read match ID for function %s.",
    488                     fun->fnode->name);
     478                    ddf_fun_get_name(fun->fnode));
    489479                return;
    490480        }
    491481
    492482        ddf_msg(LVL_DEBUG, "Adding match id '%s' with score %d to "
    493             "function %s", id, score, fun->fnode->name);
    494 
    495         int rc = ddf_fun_add_match_id(fun->fnode, id, score);
     483            "function %s", id, score, ddf_fun_get_name(fun->fnode));
     484
     485        rc = ddf_fun_add_match_id(fun->fnode, id, score);
    496486        if (rc != EOK) {
    497487                ddf_msg(LVL_ERROR, "Failed adding match ID: %s",
     
    502492}
    503493
    504 static bool prop_parse(isa_fun_t *fun, const char *line, const char *prop,
    505     void (*read_fn)(isa_fun_t *, const char *))
     494static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
     495    void (*read_fn)(isa_fun_t *, char *))
    506496{
    507497        size_t proplen = str_size(prop);
     
    518508}
    519509
    520 static void fun_prop_parse(isa_fun_t *fun, const char *line)
     510static void fun_prop_parse(isa_fun_t *fun, char *line)
    521511{
    522512        /* Skip leading spaces. */
     
    533523}
    534524
     525static void fun_hw_res_alloc(isa_fun_t *fun)
     526{
     527        fun->hw_resources.resources =
     528            (hw_resource_t *) malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
     529}
     530
     531static void fun_hw_res_free(isa_fun_t *fun)
     532{
     533        free(fun->hw_resources.resources);
     534        fun->hw_resources.resources = NULL;
     535}
     536
    535537static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa)
    536538{
    537539        char *line;
     540        char *fun_name = NULL;
    538541
    539542        /* Skip empty lines. */
    540         do {
     543        while (true) {
    541544                line = str_get_line(fun_conf, &fun_conf);
    542545
     
    546549                }
    547550
    548         } while (line_empty(line));
     551                if (!line_empty(line))
     552                        break;
     553        }
    549554
    550555        /* Get device name. */
    551         const char *fun_name = get_device_name(line);
     556        fun_name = get_device_name(line);
    552557        if (fun_name == NULL)
    553558                return NULL;
    554559
    555560        isa_fun_t *fun = isa_fun_create(isa, fun_name);
     561        free(fun_name);
    556562        if (fun == NULL) {
    557563                return NULL;
    558564        }
     565
     566        /* Allocate buffer for the list of hardware resources of the device. */
     567        fun_hw_res_alloc(fun);
    559568
    560569        /* Get properties of the device (match ids, irq and io range). */
     
    575584
    576585        /* Set device operations to the device. */
    577         fun->fnode->ops = &isa_fun_ops;
    578 
    579         ddf_msg(LVL_DEBUG, "Binding function %s.", fun->fnode->name);
     586        ddf_fun_set_ops(fun->fnode, &isa_fun_ops);
     587
     588        ddf_msg(LVL_DEBUG, "Binding function %s.", ddf_fun_get_name(fun->fnode));
    580589
    581590        /* XXX Handle error */
     
    587596}
    588597
    589 static void isa_functions_add(isa_bus_t *isa)
    590 {
    591         char *conf = fun_conf_read(CHILD_FUN_CONF_PATH);
     598static void fun_conf_parse(char *conf, isa_bus_t *isa)
     599{
    592600        while (conf != NULL && *conf != '\0') {
    593601                conf = isa_fun_read_info(conf, isa);
    594602        }
    595         free(conf);
     603}
     604
     605static void isa_functions_add(isa_bus_t *isa)
     606{
     607        char *fun_conf;
     608
     609        fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
     610        if (fun_conf != NULL) {
     611                fun_conf_parse(fun_conf, isa);
     612                free(fun_conf);
     613        }
    596614}
    597615
    598616static int isa_dev_add(ddf_dev_t *dev)
    599617{
     618        isa_bus_t *isa;
     619
    600620        ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
    601             (int) dev->handle);
    602 
    603         isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
     621            (int) ddf_dev_get_handle(dev));
     622
     623        isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
    604624        if (isa == NULL)
    605625                return ENOMEM;
     
    637657static int isa_dev_remove(ddf_dev_t *dev)
    638658{
    639         isa_bus_t *isa = ISA_BUS(dev);
     659        isa_bus_t *isa = isa_bus(dev);
     660        int rc;
    640661
    641662        fibril_mutex_lock(&isa->mutex);
     
    645666                    isa_fun_t, bus_link);
    646667
    647                 int rc = ddf_fun_offline(fun->fnode);
     668                rc = ddf_fun_offline(fun->fnode);
    648669                if (rc != EOK) {
    649670                        fibril_mutex_unlock(&isa->mutex);
    650                         ddf_msg(LVL_ERROR, "Failed offlining %s", fun->fnode->name);
     671                        ddf_msg(LVL_ERROR, "Failed offlining %s", ddf_fun_get_name(fun->fnode));
    651672                        return rc;
    652673                }
     
    655676                if (rc != EOK) {
    656677                        fibril_mutex_unlock(&isa->mutex);
    657                         ddf_msg(LVL_ERROR, "Failed unbinding %s", fun->fnode->name);
     678                        ddf_msg(LVL_ERROR, "Failed unbinding %s", ddf_fun_get_name(fun->fnode));
    658679                        return rc;
    659680                }
     
    661682                list_remove(&fun->bus_link);
    662683
     684                fun_hw_res_free(fun);
    663685                ddf_fun_destroy(fun->fnode);
    664686        }
     
    687709}
    688710
     711
     712static void isa_init()
     713{
     714        ddf_log_init(NAME);
     715        isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
     716}
     717
    689718int main(int argc, char *argv[])
    690719{
    691720        printf(NAME ": HelenOS ISA bus driver\n");
    692         ddf_log_init(NAME, LVL_ERROR);
     721        isa_init();
    693722        return ddf_driver_main(&isa_driver);
    694723}
Note: See TracChangeset for help on using the changeset viewer.