Changeset c1a8ae52 in mainline for uspace/srv/drivers/isa/isa.c


Ignore:
Timestamp:
2010-04-16T14:03:56Z (15 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5dc9622
Parents:
cd31ed8
Message:

ISA bus - parts of child device pseudo enumeration (enumeration of legacy devices found in configuration file)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/drivers/isa/isa.c

    rcd31ed8 rc1a8ae52  
    4545#include <ctype.h>
    4646#include <macros.h>
     47#include <malloc.h>
     48#include <dirent.h>
     49#include <fcntl.h>
     50#include <sys/stat.h>
    4751
    4852#include <driver.h>
     
    5155
    5256#define NAME "isa"
     57#define CHILD_DEV_CONF_PATH "/srv/drivers/isa/isa.dev"
    5358
    5459static bool isa_add_device(device_t *dev);
     
    6772};
    6873
     74typedef struct isa_child_data {
     75        hw_resource_list_t hw_resources;       
     76} isa_child_data_t;
     77
     78
     79static isa_child_data_t * create_isa_child_data()
     80{
     81         isa_child_data_t *data = (isa_child_data_t *) malloc(sizeof(isa_child_data_t));
     82         if (NULL != data) {
     83                 memset(data, 0, sizeof(isa_child_data_t));
     84         }
     85         return data;   
     86}
     87
     88static device_t * create_isa_child_dev()
     89{
     90        device_t *dev = create_device();
     91        if (NULL == dev) {
     92                return NULL;
     93        }
     94        isa_child_data_t *data = create_isa_child_data();
     95        if (NULL == data) {
     96                delete_device(dev);
     97                return NULL;
     98        }
     99       
     100        dev->driver_data = data;
     101        return dev;
     102}
     103
     104static char * read_dev_conf(const char *conf_path)
     105{
     106        printf(NAME ": read_dev_conf conf_path = %s.\n", conf_path);
     107               
     108        bool suc = false;       
     109        char *buf = NULL;
     110        bool opened = false;
     111        int fd;         
     112        off_t len = 0;
     113       
     114        fd = open(conf_path, O_RDONLY);
     115        if (fd < 0) {
     116                printf(NAME ": unable to open %s\n", conf_path);
     117                goto cleanup;
     118        }
     119        opened = true; 
     120       
     121        len = lseek(fd, 0, SEEK_END);
     122        lseek(fd, 0, SEEK_SET);
     123        if (len == 0) {
     124                printf(NAME ": read_dev_conf error: configuration file '%s' is empty.\n", conf_path);
     125                goto cleanup;           
     126        }
     127       
     128        buf = malloc(len + 1);
     129        if (buf == NULL) {
     130                printf(NAME ": read_dev_conf error: memory allocation failed.\n");
     131                goto cleanup;
     132        }       
     133       
     134        if (0 >= read(fd, buf, len)) {
     135                printf(NAME ": read_dev_conf error: unable to read file '%s'.\n", conf_path);
     136                goto cleanup;
     137        }
     138        buf[len] = 0;
     139       
     140        suc = true;
     141       
     142cleanup:
     143       
     144        if (!suc && NULL != buf) {
     145                free(buf);     
     146                buf = NULL;
     147        }
     148       
     149        if(opened) {
     150                close(fd);     
     151        }
     152       
     153        return buf;     
     154}
     155
     156static char * str_get_line(char *str) {
     157        return strtok(str, "\n");
     158}
     159
     160
     161static bool line_empty(const char *line)
     162{
     163        while (NULL != line && 0 != *line) {
     164                if(!isspace(*line)) {
     165                        return false;
     166                }               
     167                line++;         
     168        }       
     169        return true;   
     170}
     171
     172static char * get_device_name(char *line) {
     173        // skip leading spaces
     174        while (0 != *line && isspace(*line)) {
     175                line++;
     176        }
     177       
     178        // get the name part of the rest of the line
     179        strtok(line, ":");     
     180       
     181        // alloc output buffer
     182        size_t len = str_size(line);
     183        char *name = malloc(len + 1);
     184       
     185        if (NULL != name) {
     186                // copy the result to the output buffer
     187                str_cpy(name, len, line);
     188        }
     189
     190        return name;
     191}
     192
     193static inline char * skip_spaces(char *line)
     194{
     195        // skip leading spaces
     196        while (0 != *line && isspace(*line)) {
     197                line++;
     198        }
     199        return line;   
     200}
     201
     202
     203void isa_child_set_irq(device_t *dev, int irq)
     204{
     205        // TODO
     206}
     207
     208static void get_dev_irq(device_t *dev, char *val)
     209{
     210        int irq = 0;
     211        char *end = NULL;
     212       
     213        val = skip_spaces(val);
     214        irq = strtol(val, &end, 0x10);
     215       
     216        if (val != end) {
     217                isa_child_set_irq(dev, irq);           
     218        }
     219}
     220
     221static void get_dev_io_range(device_t *dev, char *val)
     222{
     223        // TODO
     224}
     225
     226static void get_dev_macth_id(device_t *dev, char *val)
     227{
     228        // TODO
     229}
     230
     231static void get_dev_prop(device_t *dev, char *line)
     232{
     233        // skip leading spaces
     234        line = skip_spaces(line);
     235       
     236        // value of the property
     237        char *val;
     238       
     239        if (NULL != (val = strtok(line, "io_range"))) {         
     240                get_dev_io_range(dev, val);
     241        } else if (NULL != (val = strtok(line, "irq"))) {
     242                get_dev_irq(dev, val);         
     243        } else if (NULL != (val = strtok(line, "match"))) {
     244                get_dev_macth_id(dev, val);
     245        }       
     246}
     247
     248static char * read_isa_dev_info(char *dev_conf, device_t *parent)
     249{
     250        char *line;
     251        bool cont = true;
     252        char *dev_name = NULL;
     253       
     254        // skip empty lines
     255        while (cont) {
     256                line = dev_conf;               
     257                dev_conf = str_get_line(line);
     258               
     259                if (NULL == dev_conf) {
     260                        // no more lines
     261                        return NULL;
     262                }
     263               
     264                if (!line_empty(line)) {
     265                        break;
     266                }
     267               
     268                if (NULL == dev_conf) {
     269                        return NULL;
     270                }
     271        }
     272       
     273        // get device name
     274        dev_name = get_device_name(line);
     275        if (NULL == dev_name) {
     276                return NULL;
     277        }
     278       
     279        device_t *dev = create_isa_child_dev();
     280        if (NULL == dev) {
     281                free(dev_name);
     282                return NULL;
     283        }
     284        dev->name = dev_name;
     285       
     286        // get properties of the device (match ids, irq and io range)
     287        cont = true;
     288        while (cont) {
     289                line = dev_conf;               
     290                dev_conf = str_get_line(line);
     291                cont = line_empty(line);
     292                // get the device's property from the configuration line and store it in the device structure
     293                if (cont) {
     294                        get_dev_prop(dev, line);
     295                }               
     296        }
     297       
     298        // TODO class & interfaces !!!
     299        child_device_register(dev, parent);
     300       
     301        return dev_conf;       
     302}
     303
     304static char * parse_dev_conf(char *conf, device_t *parent)
     305{
     306        while (NULL != conf) {
     307                conf = read_isa_dev_info(conf, parent);
     308        }       
     309}
     310
     311static void add_legacy_children(device_t *parent)
     312{
     313        char *dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH);
     314        if (NULL != dev_conf) {
     315                parse_dev_conf(dev_conf, parent);       
     316                free(dev_conf);
     317        }
     318}
    69319
    70320static bool isa_add_device(device_t *dev)
     
    72322        printf(NAME ": isa_add_device, device handle = %d\n", dev->handle);
    73323       
    74         // TODO add children
     324        // add child devices   
     325        add_legacy_children(dev);
    75326       
    76327        return true;
Note: See TracChangeset for help on using the changeset viewer.