Ignore:
File:
1 edited

Legend:

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

    r3e6a98c5 r3869c596  
    4242#include <stdio.h>
    4343#include <errno.h>
    44 #include <stdbool.h>
     44#include <bool.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
    7581#define ISA_MAX_HW_RES 5
    7682
     
    8591        fibril_mutex_t mutex;
    8692        ddf_fun_t *fnode;
     93        hw_resource_t resources[ISA_MAX_HW_RES];
    8794        hw_resource_list_t hw_resources;
    8895        link_t bus_link;
    8996} isa_fun_t;
    9097
    91 /** Obtain soft-state from device node */
    92 static 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 */
    98 static isa_fun_t *isa_fun(ddf_fun_t *fun)
    99 {
    100         return ddf_fun_data_get(fun);
    101 }
    102 
    103 static 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);
     98static hw_resource_list_t *isa_fun_get_resources(ddf_fun_t *fnode)
     99{
     100        isa_fun_t *fun = ISA_FUN(fnode);
     101        assert(fun);
    107102
    108103        return &fun->hw_resources;
    109104}
    110105
    111 static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
     106static bool isa_fun_enable_interrupt(ddf_fun_t *fnode)
    112107{
    113108        /* This is an old ugly way, copied from pci driver */
    114109        assert(fnode);
    115         isa_fun_t *fun = isa_fun(fnode);
     110        isa_fun_t *isa_fun = ISA_FUN(fnode);
    116111
    117112        sysarg_t apic;
     
    129124                return false;
    130125
    131         const hw_resource_list_t *res = &fun->hw_resources;
     126        assert(isa_fun);
     127        const hw_resource_list_t *res = &isa_fun->hw_resources;
    132128        assert(res);
    133129        for (size_t i = 0; i < res->count; ++i) {
     
    151147}
    152148
    153 static int isa_dma_channel_fun_setup(ddf_fun_t *fnode,
     149static int isa_fun_setup_dma(ddf_fun_t *fnode,
    154150    unsigned int channel, uint32_t pa, uint16_t size, uint8_t mode)
    155151{
    156152        assert(fnode);
    157         isa_fun_t *fun = isa_fun(fnode);
    158         const hw_resource_list_t *res = &fun->hw_resources;
     153        isa_fun_t *isa_fun = fnode->driver_data;
     154        assert(isa_fun);
     155        const hw_resource_list_t *res = &isa_fun->hw_resources;
    159156        assert(res);
    160157       
    161         const unsigned int ch = channel;
    162158        for (size_t i = 0; i < res->count; ++i) {
     159                /* Check for assigned channel */
    163160                if (((res->resources[i].type == DMA_CHANNEL_16) &&
    164                     (res->resources[i].res.dma_channel.dma16 == ch)) ||
     161                    (res->resources[i].res.dma_channel.dma16 == channel)) ||
    165162                    ((res->resources[i].type == DMA_CHANNEL_8) &&
    166                     (res->resources[i].res.dma_channel.dma8 == ch))) {
    167                         return dma_setup_channel(channel, pa, size, mode);
     163                    (res->resources[i].res.dma_channel.dma8 == channel))) {
     164                        return dma_channel_setup(channel, pa, size, mode);
    168165                }
    169166        }
     
    172169}
    173170
     171static 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
    174194static hw_res_ops_t isa_fun_hw_res_ops = {
    175         .get_resource_list = isa_get_fun_resources,
    176         .enable_interrupt = isa_enable_fun_interrupt,
    177         .dma_channel_setup = isa_dma_channel_fun_setup,
     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,
    178199};
    179200
    180 static ddf_dev_ops_t isa_fun_ops;
     201static ddf_dev_ops_t isa_fun_ops= {
     202        .interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops,
     203};
    181204
    182205static int isa_dev_add(ddf_dev_t *dev);
     
    212235
    213236        fibril_mutex_initialize(&fun->mutex);
     237        fun->hw_resources.resources = fun->resources;
     238
    214239        fun->fnode = fnode;
    215240        return fun;
     
    270295{
    271296        char *line = str;
     297        *next = NULL;
    272298
    273299        if (str == NULL) {
    274                 *next = NULL;
    275300                return NULL;
    276301        }
     
    282307        if (*str != '\0') {
    283308                *next = str + 1;
    284         } else {
    285                 *next = NULL;
    286309        }
    287310
     
    310333        /* Get the name part of the rest of the line. */
    311334        strtok(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 
    325 static inline char *skip_spaces(char *line)
     335        return line;
     336}
     337
     338static inline const char *skip_spaces(const char *line)
    326339{
    327340        /* Skip leading spaces. */
     
    332345}
    333346
    334 static void isa_fun_set_irq(isa_fun_t *fun, int irq)
     347static void isa_fun_add_irq(isa_fun_t *fun, int irq)
    335348{
    336349        size_t count = fun->hw_resources.count;
     
    344357
    345358                ddf_msg(LVL_NOTE, "Added irq 0x%x to function %s", irq,
    346                     ddf_fun_get_name(fun->fnode));
    347         }
    348 }
    349 
    350 static void isa_fun_set_dma(isa_fun_t *fun, int dma)
     359                    fun->fnode->name);
     360        }
     361}
     362
     363static void isa_fun_add_dma(isa_fun_t *fun, int dma)
    351364{
    352365        size_t count = fun->hw_resources.count;
     
    360373                        fun->hw_resources.count++;
    361374                        ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
    362                             ddf_fun_get_name(fun->fnode));
     375                            fun->fnode->name);
    363376                       
    364377                        return;
     
    371384                        fun->hw_resources.count++;
    372385                        ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
    373                             ddf_fun_get_name(fun->fnode));
     386                            fun->fnode->name);
    374387                       
    375388                        return;
     
    377390               
    378391                ddf_msg(LVL_WARN, "Skipped dma 0x%x for function %s", dma,
    379                     ddf_fun_get_name(fun->fnode));
    380         }
    381 }
    382 
    383 static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
     392                    fun->fnode->name);
     393        }
     394}
     395
     396static void isa_fun_add_io_range(isa_fun_t *fun, size_t addr, size_t len)
    384397{
    385398        size_t count = fun->hw_resources.count;
     
    396409                ddf_msg(LVL_NOTE, "Added io range (addr=0x%x, size=0x%x) to "
    397410                    "function %s", (unsigned int) addr, (unsigned int) len,
    398                     ddf_fun_get_name(fun->fnode));
    399         }
    400 }
    401 
    402 static void fun_parse_irq(isa_fun_t *fun, char *val)
     411                    fun->fnode->name);
     412        }
     413}
     414
     415static void fun_parse_irq(isa_fun_t *fun, const char *val)
    403416{
    404417        int irq = 0;
     
    409422
    410423        if (val != end)
    411                 isa_fun_set_irq(fun, irq);
    412 }
    413 
    414 static void fun_parse_dma(isa_fun_t *fun, char *val)
    415 {
    416         unsigned int dma = 0;
     424                isa_fun_add_irq(fun, irq);
     425}
     426
     427static void fun_parse_dma(isa_fun_t *fun, const char *val)
     428{
    417429        char *end = NULL;
    418430       
    419431        val = skip_spaces(val);
    420         dma = (unsigned int) strtol(val, &end, 10);
     432        const int dma = strtol(val, &end, 10);
    421433       
    422434        if (val != end)
    423                 isa_fun_set_dma(fun, dma);
    424 }
    425 
    426 static void fun_parse_io_range(isa_fun_t *fun, char *val)
     435                isa_fun_add_dma(fun, dma);
     436}
     437
     438static void fun_parse_io_range(isa_fun_t *fun, const char *val)
    427439{
    428440        size_t addr, len;
     
    441453                return;
    442454
    443         isa_fun_set_io_range(fun, addr, len);
    444 }
    445 
    446 static void get_match_id(char **id, char *val)
    447 {
    448         char *end = val;
     455        isa_fun_add_io_range(fun, addr, len);
     456}
     457
     458static void get_match_id(char **id, const char *val)
     459{
     460        const char *end = val;
    449461
    450462        while (!isspace(*end))
     
    456468}
    457469
    458 static void fun_parse_match_id(isa_fun_t *fun, char *val)
     470static void fun_parse_match_id(isa_fun_t *fun, const char *val)
    459471{
    460472        char *id = NULL;
    461         int score = 0;
    462473        char *end = NULL;
    463         int rc;
    464474
    465475        val = skip_spaces(val);
    466476
    467         score = (int)strtol(val, &end, 10);
     477        int score = (int)strtol(val, &end, 10);
    468478        if (val == end) {
    469479                ddf_msg(LVL_ERROR, "Cannot read match score for function "
    470                     "%s.", ddf_fun_get_name(fun->fnode));
     480                    "%s.", fun->fnode->name);
    471481                return;
    472482        }
     
    476486        if (id == NULL) {
    477487                ddf_msg(LVL_ERROR, "Cannot read match ID for function %s.",
    478                     ddf_fun_get_name(fun->fnode));
     488                    fun->fnode->name);
    479489                return;
    480490        }
    481491
    482492        ddf_msg(LVL_DEBUG, "Adding match id '%s' with score %d to "
    483             "function %s", id, score, ddf_fun_get_name(fun->fnode));
    484 
    485         rc = ddf_fun_add_match_id(fun->fnode, id, score);
     493            "function %s", id, score, fun->fnode->name);
     494
     495        int rc = ddf_fun_add_match_id(fun->fnode, id, score);
    486496        if (rc != EOK) {
    487497                ddf_msg(LVL_ERROR, "Failed adding match ID: %s",
     
    492502}
    493503
    494 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
    495     void (*read_fn)(isa_fun_t *, char *))
     504static bool prop_parse(isa_fun_t *fun, const char *line, const char *prop,
     505    void (*read_fn)(isa_fun_t *, const char *))
    496506{
    497507        size_t proplen = str_size(prop);
     
    508518}
    509519
    510 static void fun_prop_parse(isa_fun_t *fun, char *line)
     520static void fun_prop_parse(isa_fun_t *fun, const char *line)
    511521{
    512522        /* Skip leading spaces. */
     
    523533}
    524534
    525 static 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 
    531 static void fun_hw_res_free(isa_fun_t *fun)
    532 {
    533         free(fun->hw_resources.resources);
    534         fun->hw_resources.resources = NULL;
    535 }
    536 
    537535static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa)
    538536{
    539537        char *line;
    540         char *fun_name = NULL;
    541538
    542539        /* Skip empty lines. */
    543         while (true) {
     540        do {
    544541                line = str_get_line(fun_conf, &fun_conf);
    545542
     
    549546                }
    550547
    551                 if (!line_empty(line))
    552                         break;
    553         }
     548        } while (line_empty(line));
    554549
    555550        /* Get device name. */
    556         fun_name = get_device_name(line);
     551        const char *fun_name = get_device_name(line);
    557552        if (fun_name == NULL)
    558553                return NULL;
    559554
    560555        isa_fun_t *fun = isa_fun_create(isa, fun_name);
    561         free(fun_name);
    562556        if (fun == NULL) {
    563557                return NULL;
    564558        }
    565 
    566         /* Allocate buffer for the list of hardware resources of the device. */
    567         fun_hw_res_alloc(fun);
    568559
    569560        /* Get properties of the device (match ids, irq and io range). */
     
    584575
    585576        /* Set device operations to the device. */
    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));
     577        fun->fnode->ops = &isa_fun_ops;
     578
     579        ddf_msg(LVL_DEBUG, "Binding function %s.", fun->fnode->name);
    589580
    590581        /* XXX Handle error */
     
    596587}
    597588
    598 static void fun_conf_parse(char *conf, isa_bus_t *isa)
    599 {
     589static void isa_functions_add(isa_bus_t *isa)
     590{
     591        char *conf = fun_conf_read(CHILD_FUN_CONF_PATH);
    600592        while (conf != NULL && *conf != '\0') {
    601593                conf = isa_fun_read_info(conf, isa);
    602594        }
    603 }
    604 
    605 static 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         }
     595        free(conf);
    614596}
    615597
    616598static int isa_dev_add(ddf_dev_t *dev)
    617599{
    618         isa_bus_t *isa;
    619 
    620600        ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
    621             (int) ddf_dev_get_handle(dev));
    622 
    623         isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
     601            (int) dev->handle);
     602
     603        isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
    624604        if (isa == NULL)
    625605                return ENOMEM;
     
    657637static int isa_dev_remove(ddf_dev_t *dev)
    658638{
    659         isa_bus_t *isa = isa_bus(dev);
    660         int rc;
     639        isa_bus_t *isa = ISA_BUS(dev);
    661640
    662641        fibril_mutex_lock(&isa->mutex);
     
    666645                    isa_fun_t, bus_link);
    667646
    668                 rc = ddf_fun_offline(fun->fnode);
     647                int rc = ddf_fun_offline(fun->fnode);
    669648                if (rc != EOK) {
    670649                        fibril_mutex_unlock(&isa->mutex);
    671                         ddf_msg(LVL_ERROR, "Failed offlining %s", ddf_fun_get_name(fun->fnode));
     650                        ddf_msg(LVL_ERROR, "Failed offlining %s", fun->fnode->name);
    672651                        return rc;
    673652                }
     
    676655                if (rc != EOK) {
    677656                        fibril_mutex_unlock(&isa->mutex);
    678                         ddf_msg(LVL_ERROR, "Failed unbinding %s", ddf_fun_get_name(fun->fnode));
     657                        ddf_msg(LVL_ERROR, "Failed unbinding %s", fun->fnode->name);
    679658                        return rc;
    680659                }
     
    682661                list_remove(&fun->bus_link);
    683662
    684                 fun_hw_res_free(fun);
    685663                ddf_fun_destroy(fun->fnode);
    686664        }
     
    709687}
    710688
    711 
    712 static 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 
    718689int main(int argc, char *argv[])
    719690{
    720691        printf(NAME ": HelenOS ISA bus driver\n");
    721         isa_init();
     692        ddf_log_init(NAME, LVL_ERROR);
    722693        return ddf_driver_main(&isa_driver);
    723694}
Note: See TracChangeset for help on using the changeset viewer.