Ignore:
File:
1 edited

Legend:

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

    r5960b48 rd9cf684a  
    22 * Copyright (c) 2010 Lenka Trochtova
    33 * Copyright (c) 2011 Jiri Svoboda
     4 * Copyright (c) 2011 Jan Vesely
    45 * All rights reserved.
    56 *
     
    5152#include <dirent.h>
    5253#include <fcntl.h>
     54#include <sys/stat.h>
    5355#include <ipc/irc.h>
    5456#include <ipc/services.h>
    5557#include <sysinfo.h>
    5658#include <ns.h>
    57 #include <sys/stat.h>
    5859
    5960#include <ddf/driver.h>
     
    6566#include <device/hw_res.h>
    6667
     68#include "i8237.h"
     69
    6770#define NAME "isa"
    6871#define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
     
    7477#define ISA_FUN(fun) ((isa_fun_t *) ((fun)->driver_data))
    7578
    76 #define ISA_MAX_HW_RES 4
     79#define ISA_MAX_HW_RES 5
    7780
    7881typedef struct {
     
    106109        sysarg_t apic;
    107110        sysarg_t i8259;
    108 
     111       
    109112        async_sess_t *irc_sess = NULL;
    110 
     113       
    111114        if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
    112115            || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
     
    114117                    SERVICE_IRC, 0, 0);
    115118        }
    116 
     119       
    117120        if (!irc_sess)
    118121                return false;
    119 
     122       
    120123        assert(isa_fun);
    121124        const hw_resource_list_t *res = &isa_fun->hw_resources;
     
    124127                if (res->resources[i].type == INTERRUPT) {
    125128                        const int irq = res->resources[i].res.interrupt.irq;
    126 
     129                       
    127130                        async_exch_t *exch = async_exchange_begin(irc_sess);
    128131                        const int rc =
    129132                            async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq);
    130133                        async_exchange_end(exch);
    131 
     134                       
    132135                        if (rc != EOK) {
    133136                                async_hangup(irc_sess);
     
    136139                }
    137140        }
    138 
     141       
    139142        async_hangup(irc_sess);
    140143        return true;
    141144}
    142145
     146static int isa_dma_channel_fun_setup(ddf_fun_t *fnode,
     147    unsigned int channel, uint32_t pa, uint16_t size, uint8_t mode)
     148{
     149        assert(fnode);
     150        isa_fun_t *isa_fun = fnode->driver_data;
     151        const hw_resource_list_t *res = &isa_fun->hw_resources;
     152        assert(res);
     153       
     154        const unsigned int ch = channel;
     155        for (size_t i = 0; i < res->count; ++i) {
     156                if (((res->resources[i].type == DMA_CHANNEL_16) &&
     157                    (res->resources[i].res.dma_channel.dma16 == ch)) ||
     158                    ((res->resources[i].type == DMA_CHANNEL_8) &&
     159                    (res->resources[i].res.dma_channel.dma8 == ch))) {
     160                        return dma_setup_channel(channel, pa, size, mode);
     161                }
     162        }
     163       
     164        return EINVAL;
     165}
     166
    143167static hw_res_ops_t isa_fun_hw_res_ops = {
    144         &isa_get_fun_resources,
    145         &isa_enable_fun_interrupt
     168        .get_resource_list = isa_get_fun_resources,
     169        .enable_interrupt = isa_enable_fun_interrupt,
     170        .dma_channel_setup = isa_dma_channel_fun_setup,
    146171};
    147172
     
    314339}
    315340
     341static void isa_fun_set_dma(isa_fun_t *fun, int dma)
     342{
     343        size_t count = fun->hw_resources.count;
     344        hw_resource_t *resources = fun->hw_resources.resources;
     345       
     346        if (count < ISA_MAX_HW_RES) {
     347                if ((dma > 0) && (dma < 4)) {
     348                        resources[count].type = DMA_CHANNEL_8;
     349                        resources[count].res.dma_channel.dma8 = dma;
     350                       
     351                        fun->hw_resources.count++;
     352                        ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
     353                            fun->fnode->name);
     354                       
     355                        return;
     356                }
     357
     358                if ((dma > 4) && (dma < 8)) {
     359                        resources[count].type = DMA_CHANNEL_16;
     360                        resources[count].res.dma_channel.dma16 = dma;
     361                       
     362                        fun->hw_resources.count++;
     363                        ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
     364                            fun->fnode->name);
     365                       
     366                        return;
     367                }
     368               
     369                ddf_msg(LVL_WARN, "Skipped dma 0x%x for function %s", dma,
     370                    fun->fnode->name);
     371        }
     372}
     373
    316374static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
    317375{
     
    339397
    340398        val = skip_spaces(val);
    341         irq = (int)strtol(val, &end, 10);
     399        irq = (int)strtol(val, &end, 0x10);
    342400
    343401        if (val != end)
    344402                isa_fun_set_irq(fun, irq);
     403}
     404
     405static void fun_parse_dma(isa_fun_t *fun, char *val)
     406{
     407        unsigned int dma = 0;
     408        char *end = NULL;
     409       
     410        val = skip_spaces(val);
     411        dma = (unsigned int) strtol(val, &end, 10);
     412       
     413        if (val != end)
     414                isa_fun_set_dma(fun, dma);
    345415}
    346416
     
    436506        if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) &&
    437507            !prop_parse(fun, line, "irq", &fun_parse_irq) &&
     508            !prop_parse(fun, line, "dma", &fun_parse_dma) &&
    438509            !prop_parse(fun, line, "match", &fun_parse_match_id)) {
    439510
     
    446517{
    447518        fun->hw_resources.resources =
    448             (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
     519            (hw_resource_t *) malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    449520}
    450521
     
    630701
    631702
    632 static void isa_init() 
     703static void isa_init()
    633704{
    634705        ddf_log_init(NAME, LVL_ERROR);
Note: See TracChangeset for help on using the changeset viewer.