Ignore:
File:
1 edited

Legend:

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

    r9e470c0 r3e6a98c5  
    6565#include <ddf/log.h>
    6666#include <ops/hw_res.h>
    67 #include <ops/pio_window.h>
    6867
    6968#include <device/hw_res.h>
    70 #include <device/pio_window.h>
    7169
    7270#include "i8237.h"
     
    8179        ddf_dev_t *dev;
    8280        ddf_fun_t *fctl;
    83         pio_window_t pio_win;
    8481        list_t functions;
    8582} isa_bus_t;
     
    8885        fibril_mutex_t mutex;
    8986        ddf_fun_t *fnode;
    90         hw_resource_t resources[ISA_MAX_HW_RES];
    9187        hw_resource_list_t hw_resources;
    9288        link_t bus_link;
     
    105101}
    106102
    107 static hw_resource_list_t *isa_fun_get_resources(ddf_fun_t *fnode)
     103static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
    108104{
    109105        isa_fun_t *fun = isa_fun(fnode);
    110         assert(fun);
     106        assert(fun != NULL);
    111107
    112108        return &fun->hw_resources;
    113109}
    114110
    115 static bool isa_fun_enable_interrupt(ddf_fun_t *fnode)
     111static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
    116112{
    117113        /* This is an old ugly way, copied from pci driver */
    118114        assert(fnode);
    119115        isa_fun_t *fun = isa_fun(fnode);
    120         assert(fun);
    121116
    122117        sysarg_t apic;
     
    156151}
    157152
    158 static int isa_fun_setup_dma(ddf_fun_t *fnode,
    159     unsigned int channel, uint32_t pa, uint32_t size, uint8_t mode)
     153static int isa_dma_channel_fun_setup(ddf_fun_t *fnode,
     154    unsigned int channel, uint32_t pa, uint16_t size, uint8_t mode)
    160155{
    161156        assert(fnode);
    162157        isa_fun_t *fun = isa_fun(fnode);
    163         assert(fun);
    164158        const hw_resource_list_t *res = &fun->hw_resources;
    165159        assert(res);
    166 
     160       
     161        const unsigned int ch = channel;
    167162        for (size_t i = 0; i < res->count; ++i) {
    168                 /* Check for assigned channel */
    169163                if (((res->resources[i].type == DMA_CHANNEL_16) &&
    170                     (res->resources[i].res.dma_channel.dma16 == channel)) ||
     164                    (res->resources[i].res.dma_channel.dma16 == ch)) ||
    171165                    ((res->resources[i].type == DMA_CHANNEL_8) &&
    172                     (res->resources[i].res.dma_channel.dma8 == channel))) {
    173                         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);
    174168                }
    175169        }
    176 
     170       
    177171        return EINVAL;
    178172}
    179173
    180 static int isa_fun_remain_dma(ddf_fun_t *fnode,
    181     unsigned channel, size_t *size)
    182 {
    183         assert(size);
    184         assert(fnode);
    185         isa_fun_t *fun = isa_fun(fnode);
    186         assert(fun);
    187         const hw_resource_list_t *res = &fun->hw_resources;
    188         assert(res);
    189 
    190         for (size_t i = 0; i < res->count; ++i) {
    191                 /* Check for assigned channel */
    192                 if (((res->resources[i].type == DMA_CHANNEL_16) &&
    193                     (res->resources[i].res.dma_channel.dma16 == channel)) ||
    194                     ((res->resources[i].type == DMA_CHANNEL_8) &&
    195                     (res->resources[i].res.dma_channel.dma8 == channel))) {
    196                         return dma_channel_remain(channel, size);
    197                 }
    198         }
    199 
    200         return EINVAL;
    201 }
    202 
    203174static hw_res_ops_t isa_fun_hw_res_ops = {
    204         .get_resource_list = isa_fun_get_resources,
    205         .enable_interrupt = isa_fun_enable_interrupt,
    206         .dma_channel_setup = isa_fun_setup_dma,
    207         .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,
    208178};
    209179
    210 static pio_window_t *isa_fun_get_pio_window(ddf_fun_t *fnode)
    211 {
    212         ddf_dev_t *dev = ddf_fun_get_dev(fnode);
    213         isa_bus_t *isa = isa_bus(dev);
    214         assert(isa);
    215 
    216         return &isa->pio_win;
    217 }
    218 
    219 static pio_window_ops_t isa_fun_pio_window_ops = {
    220         .get_pio_window = isa_fun_get_pio_window
    221 };
    222 
    223 static ddf_dev_ops_t isa_fun_ops= {
    224         .interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops,
    225         .interfaces[PIO_WINDOW_DEV_IFACE] = &isa_fun_pio_window_ops,
    226 };
     180static ddf_dev_ops_t isa_fun_ops;
    227181
    228182static int isa_dev_add(ddf_dev_t *dev);
     
    258212
    259213        fibril_mutex_initialize(&fun->mutex);
    260         fun->hw_resources.resources = fun->resources;
    261 
    262214        fun->fnode = fnode;
    263215        return fun;
     
    318270{
    319271        char *line = str;
    320         *next = NULL;
    321272
    322273        if (str == NULL) {
     274                *next = NULL;
    323275                return NULL;
    324276        }
     
    330282        if (*str != '\0') {
    331283                *next = str + 1;
     284        } else {
     285                *next = NULL;
    332286        }
    333287
     
    356310        /* Get the name part of the rest of the line. */
    357311        strtok(line, ":");
    358         return line;
    359 }
    360 
    361 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)
    362326{
    363327        /* Skip leading spaces. */
     
    368332}
    369333
    370 static void isa_fun_add_irq(isa_fun_t *fun, int irq)
     334static void isa_fun_set_irq(isa_fun_t *fun, int irq)
    371335{
    372336        size_t count = fun->hw_resources.count;
     
    384348}
    385349
    386 static void isa_fun_add_dma(isa_fun_t *fun, int dma)
     350static void isa_fun_set_dma(isa_fun_t *fun, int dma)
    387351{
    388352        size_t count = fun->hw_resources.count;
     
    417381}
    418382
    419 static void isa_fun_add_io_range(isa_fun_t *fun, size_t addr, size_t len)
     383static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
    420384{
    421385        size_t count = fun->hw_resources.count;
    422386        hw_resource_t *resources = fun->hw_resources.resources;
    423 
    424         isa_bus_t *isa = isa_bus(ddf_fun_get_dev(fun->fnode));
    425387
    426388        if (count < ISA_MAX_HW_RES) {
    427389                resources[count].type = IO_RANGE;
    428390                resources[count].res.io_range.address = addr;
    429                 resources[count].res.io_range.address += isa->pio_win.io.base;
    430391                resources[count].res.io_range.size = len;
    431                 resources[count].res.io_range.relative = false;
    432392                resources[count].res.io_range.endianness = LITTLE_ENDIAN;
    433393
     
    440400}
    441401
    442 static void fun_parse_irq(isa_fun_t *fun, const char *val)
     402static void fun_parse_irq(isa_fun_t *fun, char *val)
    443403{
    444404        int irq = 0;
     
    449409
    450410        if (val != end)
    451                 isa_fun_add_irq(fun, irq);
    452 }
    453 
    454 static void fun_parse_dma(isa_fun_t *fun, const char *val)
    455 {
     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;
    456417        char *end = NULL;
    457418       
    458419        val = skip_spaces(val);
    459         const int dma = strtol(val, &end, 10);
     420        dma = (unsigned int) strtol(val, &end, 10);
    460421       
    461422        if (val != end)
    462                 isa_fun_add_dma(fun, dma);
    463 }
    464 
    465 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)
    466427{
    467428        size_t addr, len;
     
    480441                return;
    481442
    482         isa_fun_add_io_range(fun, addr, len);
    483 }
    484 
    485 static void get_match_id(char **id, const char *val)
    486 {
    487         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;
    488449
    489450        while (!isspace(*end))
     
    495456}
    496457
    497 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)
    498459{
    499460        char *id = NULL;
     461        int score = 0;
    500462        char *end = NULL;
     463        int rc;
    501464
    502465        val = skip_spaces(val);
    503466
    504         int score = (int)strtol(val, &end, 10);
     467        score = (int)strtol(val, &end, 10);
    505468        if (val == end) {
    506469                ddf_msg(LVL_ERROR, "Cannot read match score for function "
     
    520483            "function %s", id, score, ddf_fun_get_name(fun->fnode));
    521484
    522         int rc = ddf_fun_add_match_id(fun->fnode, id, score);
     485        rc = ddf_fun_add_match_id(fun->fnode, id, score);
    523486        if (rc != EOK) {
    524487                ddf_msg(LVL_ERROR, "Failed adding match ID: %s",
     
    529492}
    530493
    531 static bool prop_parse(isa_fun_t *fun, const char *line, const char *prop,
    532     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 *))
    533496{
    534497        size_t proplen = str_size(prop);
     
    545508}
    546509
    547 static void fun_prop_parse(isa_fun_t *fun, const char *line)
     510static void fun_prop_parse(isa_fun_t *fun, char *line)
    548511{
    549512        /* Skip leading spaces. */
     
    560523}
    561524
     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
    562537static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa)
    563538{
    564539        char *line;
     540        char *fun_name = NULL;
    565541
    566542        /* Skip empty lines. */
    567         do {
     543        while (true) {
    568544                line = str_get_line(fun_conf, &fun_conf);
    569545
     
    573549                }
    574550
    575         } while (line_empty(line));
     551                if (!line_empty(line))
     552                        break;
     553        }
    576554
    577555        /* Get device name. */
    578         const char *fun_name = get_device_name(line);
     556        fun_name = get_device_name(line);
    579557        if (fun_name == NULL)
    580558                return NULL;
    581559
    582560        isa_fun_t *fun = isa_fun_create(isa, fun_name);
     561        free(fun_name);
    583562        if (fun == NULL) {
    584563                return NULL;
    585564        }
     565
     566        /* Allocate buffer for the list of hardware resources of the device. */
     567        fun_hw_res_alloc(fun);
    586568
    587569        /* Get properties of the device (match ids, irq and io range). */
     
    614596}
    615597
    616 static void isa_functions_add(isa_bus_t *isa)
    617 {
    618         char *conf = fun_conf_read(CHILD_FUN_CONF_PATH);
     598static void fun_conf_parse(char *conf, isa_bus_t *isa)
     599{
    619600        while (conf != NULL && *conf != '\0') {
    620601                conf = isa_fun_read_info(conf, isa);
    621602        }
    622         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        }
    623614}
    624615
    625616static int isa_dev_add(ddf_dev_t *dev)
    626617{
    627         async_sess_t *sess;
    628         int rc;
     618        isa_bus_t *isa;
    629619
    630620        ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
    631621            (int) ddf_dev_get_handle(dev));
    632622
    633         isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
     623        isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
    634624        if (isa == NULL)
    635625                return ENOMEM;
     
    638628        isa->dev = dev;
    639629        list_initialize(&isa->functions);
    640 
    641         sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
    642         if (sess == NULL) {
    643                 ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the "
    644                     "parent driver.");
    645                 return ENOENT;
    646         }
    647 
    648         rc = pio_window_get(sess, &isa->pio_win);
    649         if (rc != EOK) {
    650                 ddf_msg(LVL_ERROR, "isa_dev_add failed to get PIO window "
    651                     "for the device.");
    652                 return rc;
    653         }       
    654630
    655631        /* Make the bus device more visible. Does not do anything. */
     
    682658{
    683659        isa_bus_t *isa = isa_bus(dev);
     660        int rc;
    684661
    685662        fibril_mutex_lock(&isa->mutex);
     
    689666                    isa_fun_t, bus_link);
    690667
    691                 int rc = ddf_fun_offline(fun->fnode);
     668                rc = ddf_fun_offline(fun->fnode);
    692669                if (rc != EOK) {
    693670                        fibril_mutex_unlock(&isa->mutex);
     
    705682                list_remove(&fun->bus_link);
    706683
     684                fun_hw_res_free(fun);
    707685                ddf_fun_destroy(fun->fnode);
    708686        }
     
    731709}
    732710
     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
    733718int main(int argc, char *argv[])
    734719{
    735720        printf(NAME ": HelenOS ISA bus driver\n");
    736         ddf_log_init(NAME);
     721        isa_init();
    737722        return ddf_driver_main(&isa_driver);
    738723}
Note: See TracChangeset for help on using the changeset viewer.