Changeset 68414f4a in mainline


Ignore:
Timestamp:
2011-02-13T20:03:45Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bab6388
Parents:
8b1e15ac
Message:

Refactor drivers

  • Rename soft-state structures to have the simplest names
  • Use soft-state structures as a starting point instead of DDF device or function nodes
  • Convert to standard naming scheme
Location:
uspace/drv
Files:
7 edited

Legend:

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

    r8b1e15ac r68414f4a  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    6061#define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
    6162
     63/** Obtain soft-state pointer from function node pointer */
     64#define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data))
     65
    6266#define ISA_MAX_HW_RES 4
    6367
    64 typedef struct isa_fun_data {
     68typedef struct isa_fun {
     69        function_t *fnode;
    6570        hw_resource_list_t hw_resources;
    66 } isa_fun_data_t;
    67 
    68 static hw_resource_list_t *isa_get_fun_resources(function_t *fun)
    69 {
    70         isa_fun_data_t *fun_data;
    71 
    72         fun_data = (isa_fun_data_t *)fun->driver_data;
    73         if (fun_data == NULL)
    74                 return NULL;
    75 
    76         return &fun_data->hw_resources;
    77 }
    78 
    79 static bool isa_enable_fun_interrupt(function_t *fun)
     71} isa_fun_t;
     72
     73static hw_resource_list_t *isa_get_fun_resources(function_t *fnode)
     74{
     75        isa_fun_t *fun = ISA_FUN(fnode);
     76        assert(fun != NULL);
     77
     78        return &fun->hw_resources;
     79}
     80
     81static bool isa_enable_fun_interrupt(function_t *fnode)
    8082{
    8183        // TODO
     
    8991};
    9092
    91 static device_ops_t isa_fun_dev_ops;
     93static device_ops_t isa_fun_ops;
    9294
    9395static int isa_add_device(device_t *dev);
     
    104106};
    105107
    106 
    107 static isa_fun_data_t *create_isa_fun_data()
    108 {
    109         isa_fun_data_t *data;
    110 
    111         data = (isa_fun_data_t *) malloc(sizeof(isa_fun_data_t));
    112         if (data != NULL)
    113                 memset(data, 0, sizeof(isa_fun_data_t));
    114 
    115         return data;
    116 }
    117 
    118 static function_t *create_isa_fun()
    119 {
    120         function_t *fun = create_function();
     108static isa_fun_t *isa_fun_create()
     109{
     110        isa_fun_t *fun = calloc(1, sizeof(isa_fun_t));
    121111        if (fun == NULL)
    122112                return NULL;
    123113
    124         isa_fun_data_t *data = create_isa_fun_data();
    125         if (data == NULL) {
    126                 delete_function(fun);
     114        function_t *fnode = create_function();
     115        if (fnode == NULL) {
     116                free(fun);
    127117                return NULL;
    128118        }
    129119
    130         fun->driver_data = data;
     120        fun->fnode = fnode;
     121        fnode->driver_data = fun;
    131122        return fun;
    132123}
    133124
    134 static char *read_fun_conf(const char *conf_path)
     125static char *fun_conf_read(const char *conf_path)
    135126{
    136127        bool suc = false;
     
    151142        lseek(fd, 0, SEEK_SET);
    152143        if (len == 0) {
    153                 printf(NAME ": read_fun_conf error: configuration file '%s' "
     144                printf(NAME ": fun_conf_read error: configuration file '%s' "
    154145                    "is empty.\n", conf_path);
    155146                goto cleanup;
     
    158149        buf = malloc(len + 1);
    159150        if (buf == NULL) {
    160                 printf(NAME ": read_fun_conf error: memory allocation failed.\n");
     151                printf(NAME ": fun_conf_read error: memory allocation failed.\n");
    161152                goto cleanup;
    162153        }
    163154
    164155        if (0 >= read(fd, buf, len)) {
    165                 printf(NAME ": read_fun_conf error: unable to read file '%s'.\n",
     156                printf(NAME ": fun_conf_read error: unable to read file '%s'.\n",
    166157                    conf_path);
    167158                goto cleanup;
     
    249240}
    250241
    251 static void isa_fun_set_irq(function_t *fun, int irq)
    252 {
    253         isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data;
    254 
    255         size_t count = data->hw_resources.count;
    256         hw_resource_t *resources = data->hw_resources.resources;
     242static void isa_fun_set_irq(isa_fun_t *fun, int irq)
     243{
     244        size_t count = fun->hw_resources.count;
     245        hw_resource_t *resources = fun->hw_resources.resources;
    257246
    258247        if (count < ISA_MAX_HW_RES) {
     
    260249                resources[count].res.interrupt.irq = irq;
    261250
    262                 data->hw_resources.count++;
    263 
    264                 printf(NAME ": added irq 0x%x to function %s\n", irq, fun->name);
    265         }
    266 }
    267 
    268 static void isa_fun_set_io_range(function_t *fun, size_t addr, size_t len)
    269 {
    270         isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data;
    271 
    272         size_t count = data->hw_resources.count;
    273         hw_resource_t *resources = data->hw_resources.resources;
     251                fun->hw_resources.count++;
     252
     253                printf(NAME ": added irq 0x%x to function %s\n", irq,
     254                    fun->fnode->name);
     255        }
     256}
     257
     258static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
     259{
     260        size_t count = fun->hw_resources.count;
     261        hw_resource_t *resources = fun->hw_resources.resources;
    274262
    275263        if (count < ISA_MAX_HW_RES) {
     
    279267                resources[count].res.io_range.endianness = LITTLE_ENDIAN;
    280268
    281                 data->hw_resources.count++;
     269                fun->hw_resources.count++;
    282270
    283271                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
    284272                    "function %s\n", (unsigned int) addr, (unsigned int) len,
    285                     fun->name);
    286         }
    287 }
    288 
    289 static void get_dev_irq(function_t *fun, char *val)
     273                    fun->fnode->name);
     274        }
     275}
     276
     277static void fun_parse_irq(isa_fun_t *fun, char *val)
    290278{
    291279        int irq = 0;
     
    299287}
    300288
    301 static void get_dev_io_range(function_t *fun, char *val)
     289static void fun_parse_io_range(isa_fun_t *fun, char *val)
    302290{
    303291        size_t addr, len;
     
    331319}
    332320
    333 static void get_fun_match_id(function_t *fun, char *val)
     321static void fun_parse_match_id(isa_fun_t *fun, char *val)
    334322{
    335323        char *id = NULL;
     
    337325        char *end = NULL;
    338326
    339         val = skip_spaces(val); 
     327        val = skip_spaces(val);
    340328
    341329        score = (int)strtol(val, &end, 10);
    342330        if (val == end) {
    343331                printf(NAME " : error - could not read match score for "
    344                     "function %s.\n", fun->name);
     332                    "function %s.\n", fun->fnode->name);
    345333                return;
    346334        }
     
    349337        if (match_id == NULL) {
    350338                printf(NAME " : failed to allocate match id for function %s.\n",
    351                     fun->name);
     339                    fun->fnode->name);
    352340                return;
    353341        }
     
    357345        if (id == NULL) {
    358346                printf(NAME " : error - could not read match id for "
    359                     "function %s.\n", fun->name);
     347                    "function %s.\n", fun->fnode->name);
    360348                delete_match_id(match_id);
    361349                return;
     
    366354
    367355        printf(NAME ": adding match id '%s' with score %d to function %s\n", id,
    368             score, fun->name);
    369         add_match_id(&fun->match_ids, match_id);
    370 }
    371 
    372 static bool read_fun_prop(function_t *fun, char *line, const char *prop,
    373     void (*read_fn)(function_t *, char *))
     356            score, fun->fnode->name);
     357        add_match_id(&fun->fnode->match_ids, match_id);
     358}
     359
     360static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
     361    void (*read_fn)(isa_fun_t *, char *))
    374362{
    375363        size_t proplen = str_size(prop);
     
    386374}
    387375
    388 static void get_fun_prop(function_t *fun, char *line)
     376static void fun_prop_parse(isa_fun_t *fun, char *line)
    389377{
    390378        /* Skip leading spaces. */
    391379        line = skip_spaces(line);
    392380
    393         if (!read_fun_prop(fun, line, "io_range", &get_dev_io_range) &&
    394             !read_fun_prop(fun, line, "irq", &get_dev_irq) &&
    395             !read_fun_prop(fun, line, "match", &get_fun_match_id))
     381        if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) &&
     382            !prop_parse(fun, line, "irq", &fun_parse_irq) &&
     383            !prop_parse(fun, line, "match", &fun_parse_match_id))
    396384        {
    397385            printf(NAME " error undefined device property at line '%s'\n",
     
    400388}
    401389
    402 static void child_alloc_hw_res(function_t *fun)
    403 {
    404         isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data;
    405         data->hw_resources.resources =
     390static void fun_hw_res_alloc(isa_fun_t *fun)
     391{
     392        fun->hw_resources.resources =
    406393            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    407394}
    408395
    409 static char *read_isa_fun_info(char *fun_conf, device_t *dev)
     396static char *isa_fun_read_info(char *fun_conf, device_t *dev)
    410397{
    411398        char *line;
     
    430417                return NULL;
    431418
    432         function_t *fun = create_isa_fun();
     419        isa_fun_t *fun = isa_fun_create();
    433420        if (fun == NULL) {
    434421                free(fun_name);
     
    436423        }
    437424
    438         fun->name = fun_name;
    439         fun->ftype = fun_inner;
     425        function_t *fnode = fun->fnode;
     426        fnode->name = fun_name;
     427        fnode->ftype = fun_inner;
    440428
    441429        /* Allocate buffer for the list of hardware resources of the device. */
    442         child_alloc_hw_res(fun);
     430        fun_hw_res_alloc(fun);
    443431
    444432        /* Get properties of the device (match ids, irq and io range). */
     
    455443                 * and store it in the device structure.
    456444                 */
    457                 get_fun_prop(fun, line);
    458 
    459                 //printf(NAME ": next line ='%s'\n", fun_conf);
    460                 //printf(NAME ": current line ='%s'\n", line);
     445                fun_prop_parse(fun, line);
    461446        }
    462447
    463448        /* Set device operations to the device. */
    464         fun->ops = &isa_fun_dev_ops;
     449        fnode->ops = &isa_fun_ops;
    465450
    466451        printf(NAME ": register_function(fun, dev); function is %s.\n",
    467             fun->name);
    468         register_function(fun, dev);
     452            fnode->name);
     453        register_function(fnode, dev);
    469454
    470455        return fun_conf;
    471456}
    472457
    473 static void parse_fun_conf(char *conf, device_t *dev)
     458static void fun_conf_parse(char *conf, device_t *dev)
    474459{
    475460        while (conf != NULL && *conf != '\0') {
    476                 conf = read_isa_fun_info(conf, dev);
    477         }
    478 }
    479 
    480 static void add_legacy_children(device_t *dev)
     461                conf = isa_fun_read_info(conf, dev);
     462        }
     463}
     464
     465static void isa_functions_add(device_t *dev)
    481466{
    482467        char *fun_conf;
    483468
    484         fun_conf = read_fun_conf(CHILD_FUN_CONF_PATH);
     469        fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
    485470        if (fun_conf != NULL) {
    486                 parse_fun_conf(fun_conf, dev);
     471                fun_conf_parse(fun_conf, dev);
    487472                free(fun_conf);
    488473        }
     
    502487        register_function(ctl, dev);
    503488
    504         /* Add child devices. */
    505         add_legacy_children(dev);
    506         printf(NAME ": finished the enumeration of legacy devices\n");
     489        /* Add functions as specified in the configuration file. */
     490        isa_functions_add(dev);
     491        printf(NAME ": finished the enumeration of legacy functions\n");
    507492
    508493        return EOK;
     
    511496static void isa_init()
    512497{
    513         isa_fun_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
     498        isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
    514499}
    515500
     
    524509 * @}
    525510 */
    526  
  • uspace/drv/ns8250/ns8250.c

    r8b1e15ac r68414f4a  
    1 /*                       
     1/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    6869#define DLAB_MASK (1 << 7)
    6970
     71/** Obtain soft-state structure from function node */
     72#define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data))
     73
     74/** Obtain soft-state structure from device node */
     75#define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data))
     76
    7077/** The number of bits of one data unit send by the serial port. */
    7178typedef enum {
     
    8592
    8693/** The driver data for the serial port devices. */
    87 typedef struct ns8250_dev_data {
     94typedef struct ns8250 {
     95        /** DDF device node */
     96        device_t *dev;
     97        /** DDF function node */
     98        function_t *fun;
    8899        /** Is there any client conntected to the device? */
    89100        bool client_connected;
     
    98109        /** The fibril mutex for synchronizing the access to the device. */
    99110        fibril_mutex_t mutex;
    100 } ns8250_dev_data_t;
    101 
    102 /** Create driver data for a device.
    103  *
    104  * @return              The driver data.
    105  */
    106 static ns8250_dev_data_t *create_ns8250_dev_data(void)
    107 {
    108         ns8250_dev_data_t *data;
    109        
    110         data = (ns8250_dev_data_t *) malloc(sizeof(ns8250_dev_data_t));
    111         if (NULL != data) {
    112                 memset(data, 0, sizeof(ns8250_dev_data_t));
    113                 fibril_mutex_initialize(&data->mutex);
    114         }
    115         return data;
    116 }
    117 
    118 /** Delete driver data.
    119  *
    120  * @param data          The driver data structure.
    121  */
    122 static void delete_ns8250_dev_data(ns8250_dev_data_t *data)
    123 {
    124         if (data != NULL)
    125                 free(data);
     111} ns8250_t;
     112
     113/** Create per-device soft-state structure.
     114 *
     115 * @return      Pointer to soft-state structure.
     116 */
     117static ns8250_t *ns8250_new(void)
     118{
     119        ns8250_t *ns;
     120       
     121        ns = (ns8250_t *) calloc(1, sizeof(ns8250_t));
     122        if (ns == NULL)
     123                return NULL;
     124       
     125        fibril_mutex_initialize(&ns->mutex);
     126        return ns;
     127}
     128
     129/** Delete soft-state structure.
     130 *
     131 * @param ns    The driver data structure.
     132 */
     133static void ns8250_delete(ns8250_t *ns)
     134{
     135        free(ns);
    126136}
    127137
     
    171181/** Read data from the serial port device.
    172182 *
    173  * @param dev           The serial port device.
     183 * @param fun           The serial port function
    174184 * @param buf           The ouput buffer for read data.
    175185 * @param count         The number of bytes to be read.
     
    180190static int ns8250_read(function_t *fun, char *buf, size_t count)
    181191{
     192        ns8250_t *ns = NS8250(fun);
    182193        int ret = EOK;
    183         ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
    184        
    185         fibril_mutex_lock(&data->mutex);
    186         while (!buf_is_empty(&data->input_buffer) && (size_t)ret < count) {
    187                 buf[ret] = (char)buf_pop_front(&data->input_buffer);
     194       
     195        fibril_mutex_lock(&ns->mutex);
     196        while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) {
     197                buf[ret] = (char)buf_pop_front(&ns->input_buffer);
    188198                ret++;
    189199        }
    190         fibril_mutex_unlock(&data->mutex);
     200        fibril_mutex_unlock(&ns->mutex);
    191201       
    192202        return ret;
     
    195205/** Write a character to the serial port.
    196206 *
    197  * @param data          The serial port device's driver data.
    198  * @param c             The character to be written.
    199  */
    200 static inline void ns8250_putchar(ns8250_dev_data_t *data, uint8_t c)
    201 {
    202         fibril_mutex_lock(&data->mutex);
    203         ns8250_write_8(data->port, c);
    204         fibril_mutex_unlock(&data->mutex);
     207 * @param ns            Serial port device
     208 * @param c             The character to be written
     209 */
     210static inline void ns8250_putchar(ns8250_t *ns, uint8_t c)
     211{
     212        fibril_mutex_lock(&ns->mutex);
     213        ns8250_write_8(ns->port, c);
     214        fibril_mutex_unlock(&ns->mutex);
    205215}
    206216
    207217/** Write data to the serial port.
    208218 *
    209  * @param dev           The serial port device.
    210  * @param buf           The data to be written.
    211  * @param count         The number of bytes to be written.
    212  * @return              Zero on success.
     219 * @param fun           The serial port function
     220 * @param buf           The data to be written
     221 * @param count         The number of bytes to be written
     222 * @return              Zero on success
    213223 */
    214224static int ns8250_write(function_t *fun, char *buf, size_t count)
    215225{
    216         ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
     226        ns8250_t *ns = NS8250(fun);
    217227        size_t idx;
    218228       
    219229        for (idx = 0; idx < count; idx++)
    220                 ns8250_putchar(data, (uint8_t) buf[idx]);
     230                ns8250_putchar(ns, (uint8_t) buf[idx]);
    221231       
    222232        return 0;
     
    244254};
    245255
    246 /** Clean up the serial port device structure.
    247  *
    248  * @param dev           The device structure.
    249  */
    250 static void ns8250_dev_cleanup(device_t *dev)
    251 {
    252         if (dev->driver_data != NULL) {
    253                 delete_ns8250_dev_data((ns8250_dev_data_t*) dev->driver_data);
    254                 dev->driver_data = NULL;
    255         }
    256        
    257         if (dev->parent_phone > 0) {
    258                 async_hangup(dev->parent_phone);
    259                 dev->parent_phone = 0;
     256/** Clean up the serial port soft-state
     257 *
     258 * @param ns            Serial port device
     259 */
     260static void ns8250_dev_cleanup(ns8250_t *ns)
     261{
     262        if (ns->dev->parent_phone > 0) {
     263                async_hangup(ns->dev->parent_phone);
     264                ns->dev->parent_phone = 0;
    260265        }
    261266}
     
    263268/** Enable the i/o ports of the device.
    264269 *
    265  * @param dev           The serial port device.
    266  * @return              True on success, false otherwise.
    267  */
    268 static bool ns8250_pio_enable(device_t *dev)
    269 {
    270         printf(NAME ": ns8250_pio_enable %s\n", dev->name);
    271        
    272         ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;
     270 * @param ns            Serial port device
     271 * @return              True on success, false otherwise
     272 */
     273static bool ns8250_pio_enable(ns8250_t *ns)
     274{
     275        printf(NAME ": ns8250_pio_enable %s\n", ns->dev->name);
    273276       
    274277        /* Gain control over port's registers. */
    275         if (pio_enable((void *)(uintptr_t) data->io_addr, REG_COUNT,
    276             (void **) &data->port)) {
     278        if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT,
     279            (void **) &ns->port)) {
    277280                printf(NAME ": error - cannot gain the port %#" PRIx32 " for device "
    278                     "%s.\n", data->io_addr, dev->name);
     281                    "%s.\n", ns->io_addr, ns->dev->name);
    279282                return false;
    280283        }
     
    285288/** Probe the serial port device for its presence.
    286289 *
    287  * @param dev           The serial port device.
    288  * @return              True if the device is present, false otherwise.
    289  */
    290 static bool ns8250_dev_probe(device_t *dev)
    291 {
    292         printf(NAME ": ns8250_dev_probe %s\n", dev->name);
    293        
    294         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    295         ioport8_t *port_addr = data->port;
     290 * @param ns            Serial port device
     291 * @return              True if the device is present, false otherwise
     292 */
     293static bool ns8250_dev_probe(ns8250_t *ns)
     294{
     295        printf(NAME ": ns8250_dev_probe %s\n", ns->dev->name);
     296       
     297        ioport8_t *port_addr = ns->port;
    296298        bool res = true;
    297299        uint8_t olddata;
     
    310312       
    311313        if (!res)
    312                 printf(NAME ": device %s is not present.\n", dev->name);
     314                printf(NAME ": device %s is not present.\n", ns->dev->name);
    313315       
    314316        return res;
     
    317319/** Initialize serial port device.
    318320 *
    319  * @param dev           The serial port device.
    320  * @return              Zero on success, negative error number otherwise.
    321  */
    322 static int ns8250_dev_initialize(device_t *dev)
    323 {
    324         printf(NAME ": ns8250_dev_initialize %s\n", dev->name);
     321 * @param ns            Serial port device
     322 * @return              Zero on success, negative error number otherwise
     323 */
     324static int ns8250_dev_initialize(ns8250_t *ns)
     325{
     326        printf(NAME ": ns8250_dev_initialize %s\n", ns->dev->name);
    325327       
    326328        int ret = EOK;
     
    329331        memset(&hw_resources, 0, sizeof(hw_resource_list_t));
    330332       
    331         /* Allocate driver data for the device. */
    332         ns8250_dev_data_t *data = create_ns8250_dev_data();
    333         if (data == NULL)
    334                 return ENOMEM;
    335         dev->driver_data = data;
    336        
    337333        /* Connect to the parent's driver. */
    338         dev->parent_phone = devman_parent_device_connect(dev->handle,
     334        ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle,
    339335            IPC_FLAG_BLOCKING);
    340         if (dev->parent_phone < 0) {
     336        if (ns->dev->parent_phone < 0) {
    341337                printf(NAME ": failed to connect to the parent driver of the "
    342                     "device %s.\n", dev->name);
    343                 ret = dev->parent_phone;
     338                    "device %s.\n", ns->dev->name);
     339                ret = ns->dev->parent_phone;
    344340                goto failed;
    345341        }
    346342       
    347343        /* Get hw resources. */
    348         ret = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
     344        ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources);
    349345        if (ret != EOK) {
    350346                printf(NAME ": failed to get hw resources for the device "
    351                     "%s.\n", dev->name);
     347                    "%s.\n", ns->dev->name);
    352348                goto failed;
    353349        }
     
    362358                switch (res->type) {
    363359                case INTERRUPT:
    364                         data->irq = res->res.interrupt.irq;
     360                        ns->irq = res->res.interrupt.irq;
    365361                        irq = true;
    366362                        printf(NAME ": the %s device was asigned irq = 0x%x.\n",
    367                             dev->name, data->irq);
     363                            ns->dev->name, ns->irq);
    368364                        break;
    369365                       
    370366                case IO_RANGE:
    371                         data->io_addr = res->res.io_range.address;
     367                        ns->io_addr = res->res.io_range.address;
    372368                        if (res->res.io_range.size < REG_COUNT) {
    373369                                printf(NAME ": i/o range assigned to the device "
    374                                     "%s is too small.\n", dev->name);
     370                                    "%s is too small.\n", ns->dev->name);
    375371                                ret = ELIMIT;
    376372                                goto failed;
     
    378374                        ioport = true;
    379375                        printf(NAME ": the %s device was asigned i/o address = "
    380                             "0x%x.\n", dev->name, data->io_addr);
     376                            "0x%x.\n", ns->dev->name, ns->io_addr);
    381377                        break;
    382378                       
     
    388384        if (!irq || !ioport) {
    389385                printf(NAME ": missing hw resource(s) for the device %s.\n",
    390                     dev->name);
     386                    ns->dev->name);
    391387                ret = ENOENT;
    392388                goto failed;
     
    397393       
    398394failed:
    399         ns8250_dev_cleanup(dev);
     395        ns8250_dev_cleanup(ns);
    400396        hw_res_clean_resource_list(&hw_resources);
    401397        return ret;
     
    404400/** Enable interrupts on the serial port device.
    405401 *
    406  * Interrupt when data is received.
     402 * Interrupt when data is received
    407403 *
    408404 * @param port          The base address of the serial port device's ports.
     
    416412/** Disable interrupts on the serial port device.
    417413 *
    418  * @param port          The base address of the serial port device's ports.
     414 * @param port          The base address of the serial port device's ports
    419415 */
    420416static inline void ns8250_port_interrupts_disable(ioport8_t *port)
     
    425421/** Enable interrupts for the serial port device.
    426422 *
    427  * @param dev           The device.
    428  * @return              Zero on success, negative error number otherwise.
    429  */
    430 static int ns8250_interrupt_enable(device_t *dev)
    431 {
    432         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    433        
     423 * @param ns            Serial port device
     424 * @return              Zero on success, negative error number otherwise
     425 */
     426static int ns8250_interrupt_enable(ns8250_t *ns)
     427{
    434428        /* Enable interrupt on the serial port. */
    435         ns8250_port_interrupts_enable(data->port);
     429        ns8250_port_interrupts_enable(ns->port);
    436430       
    437431        return EOK;
     
    618612 * Set the default parameters of the serial communication.
    619613 *
    620  * @param dev           The serial port device.
    621  */
    622 static void ns8250_initialize_port(device_t *dev)
    623 {
    624         ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;
    625         ioport8_t *port = data->port;
     614 * @param ns            Serial port device
     615 */
     616static void ns8250_initialize_port(ns8250_t *ns)
     617{
     618        ioport8_t *port = ns->port;
    626619       
    627620        /* Disable interrupts. */
     
    643636 * buffer.
    644637 *
    645  * @param dev           The serial port device.
    646  */
    647 static void ns8250_read_from_device(device_t *dev)
    648 {
    649         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    650         ioport8_t *port = data->port;
     638 * @param ns            Serial port device
     639 */
     640static void ns8250_read_from_device(ns8250_t *ns)
     641{
     642        ioport8_t *port = ns->port;
    651643        bool cont = true;
    652644       
    653645        while (cont) {
    654                 fibril_mutex_lock(&data->mutex);
     646                fibril_mutex_lock(&ns->mutex);
    655647               
    656648                cont = ns8250_received(port);
     
    658650                        uint8_t val = ns8250_read_8(port);
    659651                       
    660                         if (data->client_connected) {
    661                                 if (!buf_push_back(&data->input_buffer, val)) {
     652                        if (ns->client_connected) {
     653                                if (!buf_push_back(&ns->input_buffer, val)) {
    662654                                        printf(NAME ": buffer overflow on "
    663                                             "%s.\n", dev->name);
     655                                            "%s.\n", ns->dev->name);
    664656                                } else {
    665657                                        printf(NAME ": the character %c saved "
    666658                                            "to the buffer of %s.\n",
    667                                             val, dev->name);
     659                                            val, ns->dev->name);
    668660                                }
    669661                        }
    670662                }
    671663               
    672                 fibril_mutex_unlock(&data->mutex);
     664                fibril_mutex_unlock(&ns->mutex);
    673665                fibril_yield();
    674666        }
     
    685677    ipc_call_t *icall)
    686678{
    687         ns8250_read_from_device(dev);
     679        ns8250_read_from_device(NS8250_FROM_DEV(dev));
    688680}
    689681
    690682/** Register the interrupt handler for the device.
    691683 *
     684 * @param ns            Serial port device
     685 */
     686static inline int ns8250_register_interrupt_handler(ns8250_t *ns)
     687{
     688        return register_interrupt_handler(ns->dev, ns->irq,
     689            ns8250_interrupt_handler, NULL);
     690}
     691
     692/** Unregister the interrupt handler for the device.
     693 *
     694 * @param ns            Serial port device
     695 */
     696static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns)
     697{
     698        return unregister_interrupt_handler(ns->dev, ns->irq);
     699}
     700
     701/** The add_device callback method of the serial port driver.
     702 *
     703 * Probe and initialize the newly added device.
     704 *
    692705 * @param dev           The serial port device.
    693706 */
    694 static inline int ns8250_register_interrupt_handler(device_t *dev)
    695 {
    696         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    697        
    698         return register_interrupt_handler(dev, data->irq,
    699             ns8250_interrupt_handler, NULL);
    700 }
    701 
    702 /** Unregister the interrupt handler for the device.
    703  *
    704  * @param dev           The serial port device.
    705  */
    706 static inline int ns8250_unregister_interrupt_handler(device_t *dev)
    707 {
    708         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    709        
    710         return unregister_interrupt_handler(dev, data->irq);
    711 }
    712 
    713 /** The add_device callback method of the serial port driver.
    714  *
    715  * Probe and initialize the newly added device.
    716  *
    717  * @param dev           The serial port device.
    718  */
    719707static int ns8250_add_device(device_t *dev)
    720708{
    721         function_t *fun;
    722 
     709        ns8250_t *ns = NULL;
     710        function_t *fun = NULL;
     711        bool need_cleanup = false;
     712        int rc;
     713       
    723714        printf(NAME ": ns8250_add_device %s (handle = %d)\n",
    724715            dev->name, (int) dev->handle);
    725716       
    726         int res = ns8250_dev_initialize(dev);
    727         if (res != EOK)
    728                 return res;
    729        
    730         if (!ns8250_pio_enable(dev)) {
    731                 ns8250_dev_cleanup(dev);
    732                 return EADDRNOTAVAIL;
     717        /* Allocate soft-state for the device */
     718        ns = ns8250_new();
     719        if (ns == NULL) {
     720                rc = ENOMEM;
     721                goto fail;
     722        }
     723       
     724        ns->dev = dev;
     725        dev->driver_data = ns;
     726       
     727        rc = ns8250_dev_initialize(ns);
     728        if (rc != EOK)
     729                goto fail;
     730       
     731        need_cleanup = true;
     732       
     733        if (!ns8250_pio_enable(ns)) {
     734                rc = EADDRNOTAVAIL;
     735                goto fail;
    733736        }
    734737       
    735738        /* Find out whether the device is present. */
    736         if (!ns8250_dev_probe(dev)) {
    737                 ns8250_dev_cleanup(dev);
    738                 return ENOENT;
     739        if (!ns8250_dev_probe(ns)) {
     740                rc = ENOENT;
     741                goto fail;
    739742        }
    740743       
    741744        /* Serial port initialization (baud rate etc.). */
    742         ns8250_initialize_port(dev);
     745        ns8250_initialize_port(ns);
    743746       
    744747        /* Register interrupt handler. */
    745         if (ns8250_register_interrupt_handler(dev) != EOK) {
     748        if (ns8250_register_interrupt_handler(ns) != EOK) {
    746749                printf(NAME ": failed to register interrupt handler.\n");
    747                 ns8250_dev_cleanup(dev);
    748                 return res;
     750                rc = EADDRNOTAVAIL;
     751                goto fail;
    749752        }
    750753       
    751754        /* Enable interrupt. */
    752         res = ns8250_interrupt_enable(dev);
    753         if (res != EOK) {
     755        rc = ns8250_interrupt_enable(ns);
     756        if (rc != EOK) {
    754757                printf(NAME ": failed to enable the interrupt. Error code = "
    755                     "%d.\n", res);
    756                 ns8250_dev_cleanup(dev);
    757                 ns8250_unregister_interrupt_handler(dev);
    758                 return res;
    759         }
    760 
     758                    "%d.\n", rc);
     759                goto fail;
     760        }
     761       
    761762        fun = create_function();
    762763        fun->ftype = fun_exposed;
     
    766767        fun->ops = &ns8250_dev_ops;
    767768        register_function(fun, dev);
     769        ns->fun = fun;
    768770       
    769771        add_function_to_class(fun, "serial");
     
    773775       
    774776        return EOK;
     777fail:
     778        if (need_cleanup)
     779                ns8250_dev_cleanup(ns);
     780        if (ns != NULL)
     781                ns8250_delete(ns);
     782        return rc;
    775783}
    776784
     
    784792static int ns8250_open(function_t *fun)
    785793{
    786         ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
     794        ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
    787795        int res;
    788796       
     
    808816static void ns8250_close(function_t *fun)
    809817{
    810         ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;
     818        ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
    811819       
    812820        fibril_mutex_lock(&data->mutex);
     
    833841    unsigned int *word_length, unsigned int* stop_bits)
    834842{
    835         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     843        ns8250_t *data = (ns8250_t *) dev->driver_data;
    836844        ioport8_t *port = data->port;
    837845       
     
    864872            stop_bits);
    865873       
    866         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     874        ns8250_t *data = (ns8250_t *) dev->driver_data;
    867875        ioport8_t *port = data->port;
    868876        int ret;
  • uspace/drv/pciintel/pci.c

    r8b1e15ac r68414f4a  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    6162        ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
    6263
    63 static hw_resource_list_t *pciintel_get_child_resources(function_t *fun)
    64 {
    65         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    66        
    67         if (fun_data == NULL)
     64/** Obtain PCI function soft-state from DDF function node */
     65#define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
     66
     67/** Obtain PCI bus soft-state from DDF device node */
     68#define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
     69
     70/** Obtain PCI bus soft-state from function soft-state */
     71#define PCI_BUS_FROM_FUN(fun) (PCI_BUS(fun->fnode->dev))
     72
     73static hw_resource_list_t *pciintel_get_resources(function_t *fnode)
     74{
     75        pci_fun_t *fun = PCI_FUN(fnode);
     76       
     77        if (fun == NULL)
    6878                return NULL;
    69         return &fun_data->hw_resources;
    70 }
    71 
    72 static bool pciintel_enable_child_interrupt(function_t *fun)
     79        return &fun->hw_resources;
     80}
     81
     82static bool pciintel_enable_interrupt(function_t *fnode)
    7383{
    7484        /* TODO */
     
    7787}
    7888
    79 static hw_res_ops_t pciintel_child_hw_res_ops = {
    80         &pciintel_get_child_resources,
    81         &pciintel_enable_child_interrupt
     89static hw_res_ops_t pciintel_hw_res_ops = {
     90        &pciintel_get_resources,
     91        &pciintel_enable_interrupt
    8292};
    8393
    84 static device_ops_t pci_child_ops;
     94static device_ops_t pci_fun_ops;
    8595
    8696static int pci_add_device(device_t *);
    8797
    88 /** The pci bus driver's standard operations. */
     98/** PCI bus driver standard operations */
    8999static driver_ops_t pci_ops = {
    90100        .add_device = &pci_add_device
    91101};
    92102
    93 /** The pci bus driver structure. */
     103/** PCI bus driver structure */
    94104static driver_t pci_driver = {
    95105        .name = NAME,
     
    97107};
    98108
    99 typedef struct pciintel_bus_data {
    100         uint32_t conf_io_addr;
    101         void *conf_data_port;
    102         void *conf_addr_port;
    103         fibril_mutex_t conf_mutex;
    104 } pci_bus_data_t;
    105 
    106 static pci_bus_data_t *create_pci_bus_data(void)
    107 {
    108         pci_bus_data_t *bus_data;
    109        
    110         bus_data = (pci_bus_data_t *) malloc(sizeof(pci_bus_data_t));
    111         if (bus_data != NULL) {
    112                 memset(bus_data, 0, sizeof(pci_bus_data_t));
    113                 fibril_mutex_initialize(&bus_data->conf_mutex);
    114         }
    115 
    116         return bus_data;
    117 }
    118 
    119 static void delete_pci_bus_data(pci_bus_data_t *bus_data)
    120 {
    121         free(bus_data);
    122 }
    123 
    124 static void pci_conf_read(function_t *fun, int reg, uint8_t *buf, size_t len)
    125 {
    126         assert(fun->dev != NULL);
    127        
    128         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    129         pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data;
    130        
    131         fibril_mutex_lock(&bus_data->conf_mutex);
     109static pci_bus_t *pci_bus_new(void)
     110{
     111        pci_bus_t *bus;
     112       
     113        bus = (pci_bus_t *) malloc(sizeof(pci_bus_t));
     114        if (bus != NULL) {
     115                memset(bus, 0, sizeof(pci_bus_t));
     116                fibril_mutex_initialize(&bus->conf_mutex);
     117        }
     118
     119        return bus;
     120}
     121
     122static void pci_bus_delete(pci_bus_t *bus)
     123{
     124        free(bus);
     125}
     126
     127static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     128{
     129        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     130       
     131        fibril_mutex_lock(&bus->conf_mutex);
    132132       
    133133        uint32_t conf_addr;
    134         conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_data->fn, reg);
    135         void *addr = bus_data->conf_data_port + (reg & 3);
    136        
    137         pio_write_32(bus_data->conf_addr_port, conf_addr);
     134        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     135        void *addr = bus->conf_data_port + (reg & 3);
     136       
     137        pio_write_32(bus->conf_addr_port, conf_addr);
    138138       
    139139        switch (len) {
     
    149149        }
    150150       
    151         fibril_mutex_unlock(&bus_data->conf_mutex);
    152 }
    153 
    154 static void pci_conf_write(function_t *fun, int reg, uint8_t *buf, size_t len)
    155 {
    156         assert(fun->dev != NULL);
    157        
    158         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    159         pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data;
    160        
    161         fibril_mutex_lock(&bus_data->conf_mutex);
     151        fibril_mutex_unlock(&bus->conf_mutex);
     152}
     153
     154static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     155{
     156        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     157       
     158        fibril_mutex_lock(&bus->conf_mutex);
    162159       
    163160        uint32_t conf_addr;
    164         conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_data->fn, reg);
    165         void *addr = bus_data->conf_data_port + (reg & 3);
    166        
    167         pio_write_32(bus_data->conf_addr_port, conf_addr);
     161        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     162        void *addr = bus->conf_data_port + (reg & 3);
     163       
     164        pio_write_32(bus->conf_addr_port, conf_addr);
    168165       
    169166        switch (len) {
     
    179176        }
    180177       
    181         fibril_mutex_unlock(&bus_data->conf_mutex);
    182 }
    183 
    184 uint8_t pci_conf_read_8(function_t *fun, int reg)
     178        fibril_mutex_unlock(&bus->conf_mutex);
     179}
     180
     181uint8_t pci_conf_read_8(pci_fun_t *fun, int reg)
    185182{
    186183        uint8_t res;
     
    189186}
    190187
    191 uint16_t pci_conf_read_16(function_t *fun, int reg)
     188uint16_t pci_conf_read_16(pci_fun_t *fun, int reg)
    192189{
    193190        uint16_t res;
     
    196193}
    197194
    198 uint32_t pci_conf_read_32(function_t *fun, int reg)
     195uint32_t pci_conf_read_32(pci_fun_t *fun, int reg)
    199196{
    200197        uint32_t res;
     
    203200}
    204201
    205 void pci_conf_write_8(function_t *fun, int reg, uint8_t val)
     202void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val)
    206203{
    207204        pci_conf_write(fun, reg, (uint8_t *) &val, 1);
    208205}
    209206
    210 void pci_conf_write_16(function_t *fun, int reg, uint16_t val)
     207void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val)
    211208{
    212209        pci_conf_write(fun, reg, (uint8_t *) &val, 2);
    213210}
    214211
    215 void pci_conf_write_32(function_t *fun, int reg, uint32_t val)
     212void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val)
    216213{
    217214        pci_conf_write(fun, reg, (uint8_t *) &val, 4);
    218215}
    219216
    220 void create_pci_match_ids(function_t *fun)
    221 {
    222         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     217void pci_fun_create_match_ids(pci_fun_t *fun)
     218{
    223219        match_id_t *match_id = NULL;
    224220        char *match_id_str;
     
    227223        if (match_id != NULL) {
    228224                asprintf(&match_id_str, "pci/ven=%04x&dev=%04x",
    229                     fun_data->vendor_id, fun_data->device_id);
     225                    fun->vendor_id, fun->device_id);
    230226                match_id->id = match_id_str;
    231227                match_id->score = 90;
    232                 add_match_id(&fun->match_ids, match_id);
     228                add_match_id(&fun->fnode->match_ids, match_id);
    233229        }
    234230
     
    236232}
    237233
    238 void
    239 pci_add_range(function_t *fun, uint64_t range_addr, size_t range_size, bool io)
    240 {
    241         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    242         hw_resource_list_t *hw_res_list = &fun_data->hw_resources;
     234void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size,
     235    bool io)
     236{
     237        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    243238        hw_resource_t *hw_resources =  hw_res_list->resources;
    244239        size_t count = hw_res_list->count;
     
    265260 * address add it to the devices hw resource list.
    266261 *
    267  * @param dev   The pci device.
     262 * @param fun   PCI function
    268263 * @param addr  The address of the BAR in the PCI configuration address space of
    269  *              the device.
    270  * @return      The addr the address of the BAR which should be read next.
     264 *              the device
     265 * @return      The addr the address of the BAR which should be read next
    271266 */
    272 int pci_read_bar(function_t *fun, int addr)
     267int pci_read_bar(pci_fun_t *fun, int addr)
    273268{       
    274269        /* Value of the BAR */
     
    322317       
    323318        if (range_addr != 0) {
    324                 printf(NAME ": function %s : ", fun->name);
     319                printf(NAME ": function %s : ", fun->fnode->name);
    325320                printf("address = %" PRIx64, range_addr);
    326321                printf(", size = %x\n", (unsigned int) range_size);
     
    335330}
    336331
    337 void pci_add_interrupt(function_t *fun, int irq)
    338 {
    339         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    340         hw_resource_list_t *hw_res_list = &fun_data->hw_resources;
     332void pci_add_interrupt(pci_fun_t *fun, int irq)
     333{
     334        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    341335        hw_resource_t *hw_resources = hw_res_list->resources;
    342336        size_t count = hw_res_list->count;
     
    350344        hw_res_list->count++;
    351345       
    352         printf(NAME ": function %s uses irq %x.\n", fun->name, irq);
    353 }
    354 
    355 void pci_read_interrupt(function_t *fun)
     346        printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq);
     347}
     348
     349void pci_read_interrupt(pci_fun_t *fun)
    356350{
    357351        uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
     
    362356/** Enumerate (recursively) and register the devices connected to a pci bus.
    363357 *
    364  * @param dev           The host-to-pci bridge device.
    365  * @param bus_num       The bus number.
     358 * @param bus           Host-to-PCI bridge
     359 * @param bus_num       Bus number
    366360 */
    367 void pci_bus_scan(device_t *dev, int bus_num)
    368 {
    369         function_t *fun = create_function();
    370         pci_fun_data_t *fun_data = create_pci_fun_data();
    371         fun->driver_data = fun_data;
     361void pci_bus_scan(pci_bus_t *bus, int bus_num)
     362{
     363        function_t *fnode = create_function();
     364        pci_fun_t *fun = pci_fun_new();
     365        fnode->driver_data = fun;
    372366       
    373367        int child_bus = 0;
     
    377371
    378372        /* We need this early, before registering. */
    379         fun->dev = dev;
     373        fun->fnode = fnode;
     374        fnode->dev = bus->dnode;
     375        fnode->driver_data = fun;
    380376       
    381377        for (dnum = 0; dnum < 32; dnum++) {
    382378                multi = true;
    383379                for (fnum = 0; multi && fnum < 8; fnum++) {
    384                         init_pci_fun_data(fun_data, bus_num, dnum, fnum);
    385                         fun_data->vendor_id = pci_conf_read_16(fun,
     380                        pci_fun_init(fun, bus_num, dnum, fnum);
     381                        fun->vendor_id = pci_conf_read_16(fun,
    386382                            PCI_VENDOR_ID);
    387                         fun_data->device_id = pci_conf_read_16(fun,
     383                        fun->device_id = pci_conf_read_16(fun,
    388384                            PCI_DEVICE_ID);
    389                         if (fun_data->vendor_id == 0xffff) {
     385                        if (fun->vendor_id == 0xffff) {
    390386                                /*
    391387                                 * The device is not present, go on scanning the
     
    406402                        header_type = header_type & 0x7F;
    407403                       
    408                         create_pci_fun_name(fun);
     404                        pci_fun_create_name(fun);
    409405                       
    410406                        pci_alloc_resource_list(fun);
     
    412408                        pci_read_interrupt(fun);
    413409                       
    414                         fun->ftype = fun_inner;
    415                         fun->ops = &pci_child_ops;
     410                        fnode->ftype = fun_inner;
     411                        fnode->ops = &pci_fun_ops;
    416412                       
    417413                        printf(NAME ": adding new function %s.\n",
    418                             fun->name);
    419                        
    420                         create_pci_match_ids(fun);
    421                        
    422                         if (register_function(fun, dev) != EOK) {
     414                            fnode->name);
     415                       
     416                        pci_fun_create_match_ids(fun);
     417                       
     418                        if (register_function(fnode, bus->dnode) != EOK) {
    423419                                pci_clean_resource_list(fun);
    424                                 clean_match_ids(&fun->match_ids);
    425                                 free((char *) fun->name);
    426                                 fun->name = NULL;
     420                                clean_match_ids(&fnode->match_ids);
     421                                free((char *) fnode->name);
     422                                fnode->name = NULL;
    427423                                continue;
    428424                        }
     
    435431                                    "secondary bus number = %d.\n", bus_num);
    436432                                if (child_bus > bus_num)
    437                                         pci_bus_scan(dev, child_bus);
     433                                        pci_bus_scan(bus, child_bus);
    438434                        }
    439435                       
    440436                        /* Alloc new aux. fun. structure. */
    441                         fun = create_function();
     437                        fnode = create_function();
    442438
    443439                        /* We need this early, before registering. */
    444                         fun->dev = dev;
    445 
    446                         fun_data = create_pci_fun_data();
    447                         fun->driver_data = fun_data;
     440                        fnode->dev = bus->dnode;
     441
     442                        fun = pci_fun_new();
     443                        fun->fnode = fnode;
     444                        fnode->driver_data = fun;
    448445                }
    449446        }
    450447       
    451         if (fun_data->vendor_id == 0xffff) {
    452                 delete_function(fun);
     448        if (fun->vendor_id == 0xffff) {
     449                delete_function(fnode);
    453450                /* Free the auxiliary function structure. */
    454                 delete_pci_fun_data(fun_data);
    455         }
    456 }
    457 
    458 static int pci_add_device(device_t *dev)
     451                pci_fun_delete(fun);
     452        }
     453}
     454
     455static int pci_add_device(device_t *dnode)
    459456{
    460457        int rc;
    461 
     458       
    462459        printf(NAME ": pci_add_device\n");
    463460       
    464         pci_bus_data_t *bus_data = create_pci_bus_data();
    465         if (bus_data == NULL) {
     461        pci_bus_t *bus = pci_bus_new();
     462        if (bus == NULL) {
    466463                printf(NAME ": pci_add_device allocation failed.\n");
    467464                return ENOMEM;
    468465        }
    469        
    470         dev->parent_phone = devman_parent_device_connect(dev->handle,
     466        bus->dnode = dnode;
     467        dnode->driver_data = bus;
     468       
     469        dnode->parent_phone = devman_parent_device_connect(dnode->handle,
    471470            IPC_FLAG_BLOCKING);
    472         if (dev->parent_phone < 0) {
     471        if (dnode->parent_phone < 0) {
    473472                printf(NAME ": pci_add_device failed to connect to the "
    474473                    "parent's driver.\n");
    475                 delete_pci_bus_data(bus_data);
    476                 return dev->parent_phone;
     474                pci_bus_delete(bus);
     475                return dnode->parent_phone;
    477476        }
    478477       
    479478        hw_resource_list_t hw_resources;
    480479       
    481         rc = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
     480        rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
    482481        if (rc != EOK) {
    483482                printf(NAME ": pci_add_device failed to get hw resources for "
    484483                    "the device.\n");
    485                 delete_pci_bus_data(bus_data);
    486                 async_hangup(dev->parent_phone);
     484                pci_bus_delete(bus);
     485                async_hangup(dnode->parent_phone);
    487486                return rc;
    488487        }       
     
    495494        assert(hw_resources.resources[0].res.io_range.size == 8);
    496495       
    497         bus_data->conf_io_addr =
     496        bus->conf_io_addr =
    498497            (uint32_t) hw_resources.resources[0].res.io_range.address;
    499498       
    500         if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8,
    501             &bus_data->conf_addr_port)) {
     499        if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
     500            &bus->conf_addr_port)) {
    502501                printf(NAME ": failed to enable configuration ports.\n");
    503                 delete_pci_bus_data(bus_data);
    504                 async_hangup(dev->parent_phone);
     502                pci_bus_delete(bus);
     503                async_hangup(dnode->parent_phone);
    505504                hw_res_clean_resource_list(&hw_resources);
    506505                return EADDRNOTAVAIL;
    507506        }
    508         bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4;
    509        
    510         dev->driver_data = bus_data;
    511        
    512         /* Make the bus device more visible. Does not do anything. */
     507        bus->conf_data_port = (char *) bus->conf_addr_port + 4;
     508       
     509        /* Make the bus device more visible. It has no use yet. */
    513510        printf(NAME ": adding a 'ctl' function\n");
    514 
     511       
    515512        function_t *ctl = create_function();
    516513        ctl->ftype = fun_exposed;
    517514        ctl->name = "ctl";
    518         register_function(ctl, dev);
    519        
    520         /* Enumerate child devices. */
     515        register_function(ctl, dnode);
     516       
     517        /* Enumerate functions. */
    521518        printf(NAME ": scanning the bus\n");
    522         pci_bus_scan(dev, 0);
     519        pci_bus_scan(bus, 0);
    523520       
    524521        hw_res_clean_resource_list(&hw_resources);
     
    529526static void pciintel_init(void)
    530527{
    531         pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops;
    532 }
    533 
    534 pci_fun_data_t *create_pci_fun_data(void)
    535 {
    536         pci_fun_data_t *res = (pci_fun_data_t *) malloc(sizeof(pci_fun_data_t));
     528        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     529}
     530
     531pci_fun_t *pci_fun_new(void)
     532{
     533        pci_fun_t *res = (pci_fun_t *) malloc(sizeof(pci_fun_t));
    537534       
    538535        if (res != NULL)
    539                 memset(res, 0, sizeof(pci_fun_data_t));
     536                memset(res, 0, sizeof(pci_fun_t));
    540537        return res;
    541538}
    542539
    543 void init_pci_fun_data(pci_fun_data_t *fun_data, int bus, int dev, int fn)
    544 {
    545         fun_data->bus = bus;
    546         fun_data->dev = dev;
    547         fun_data->fn = fn;
    548 }
    549 
    550 void delete_pci_fun_data(pci_fun_data_t *fun_data)
    551 {
    552         if (fun_data != NULL) {
    553                 hw_res_clean_resource_list(&fun_data->hw_resources);
    554                 free(fun_data);
    555         }
    556 }
    557 
    558 void create_pci_fun_name(function_t *fun)
    559 {
    560         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     540void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn)
     541{
     542        fun->bus = bus;
     543        fun->dev = dev;
     544        fun->fn = fn;
     545}
     546
     547void pci_fun_delete(pci_fun_t *fun)
     548{
     549        if (fun != NULL) {
     550                hw_res_clean_resource_list(&fun->hw_resources);
     551                free(fun);
     552        }
     553}
     554
     555void pci_fun_create_name(pci_fun_t *fun)
     556{
    561557        char *name = NULL;
    562558       
    563         asprintf(&name, "%02x:%02x.%01x", fun_data->bus, fun_data->dev,
    564             fun_data->fn);
    565         fun->name = name;
    566 }
    567 
    568 bool pci_alloc_resource_list(function_t *fun)
    569 {
    570         pci_fun_data_t *fun_data = (pci_fun_data_t *)fun->driver_data;
    571        
    572         fun_data->hw_resources.resources =
     559        asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev,
     560            fun->fn);
     561        fun->fnode->name = name;
     562}
     563
     564bool pci_alloc_resource_list(pci_fun_t *fun)
     565{
     566        fun->hw_resources.resources =
    573567            (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t));
    574         return fun_data->hw_resources.resources != NULL;
    575 }
    576 
    577 void pci_clean_resource_list(function_t *fun)
    578 {
    579         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    580        
    581         if (fun_data->hw_resources.resources != NULL) {
    582                 free(fun_data->hw_resources.resources);
    583                 fun_data->hw_resources.resources = NULL;
    584         }
    585 }
    586 
    587 /** Read the base address registers (BARs) of the device and adds the addresses
    588  * to its hw resource list.
     568        return fun->hw_resources.resources != NULL;
     569}
     570
     571void pci_clean_resource_list(pci_fun_t *fun)
     572{
     573        if (fun->hw_resources.resources != NULL) {
     574                free(fun->hw_resources.resources);
     575                fun->hw_resources.resources = NULL;
     576        }
     577}
     578
     579/** Read the base address registers (BARs) of the function and add the addresses
     580 * to its HW resource list.
    589581 *
    590  * @param dev the pci device.
     582 * @param fun   PCI function
    591583 */
    592 void pci_read_bars(function_t *fun)
     584void pci_read_bars(pci_fun_t *fun)
    593585{
    594586        /*
  • uspace/drv/pciintel/pci.h

    r8b1e15ac r68414f4a  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4546
    4647typedef struct pci_fun_data {
     48        function_t *fnode;
     49
    4750        int bus;
    4851        int dev;
     
    5154        int device_id;
    5255        hw_resource_list_t hw_resources;
    53 } pci_fun_data_t;
     56} pci_fun_t;
    5457
    55 extern void create_pci_match_ids(function_t *);
     58typedef struct pciintel_bus {
     59        /** DDF device node */
     60        device_t *dnode;
     61        uint32_t conf_io_addr;
     62        void *conf_data_port;
     63        void *conf_addr_port;
     64        fibril_mutex_t conf_mutex;
     65} pci_bus_t;
    5666
    57 extern uint8_t pci_conf_read_8(function_t *, int);
    58 extern uint16_t pci_conf_read_16(function_t *, int);
    59 extern uint32_t pci_conf_read_32(function_t *, int);
    60 extern void pci_conf_write_8(function_t *, int, uint8_t);
    61 extern void pci_conf_write_16(function_t *, int, uint16_t);
    62 extern void pci_conf_write_32(function_t *, int, uint32_t);
     67extern void pci_fun_create_match_ids(pci_fun_t *);
    6368
    64 extern void pci_add_range(function_t *, uint64_t, size_t, bool);
    65 extern int pci_read_bar(function_t *, int);
    66 extern void pci_read_interrupt(function_t *);
    67 extern void pci_add_interrupt(function_t *, int);
     69extern uint8_t pci_conf_read_8(pci_fun_t *, int);
     70extern uint16_t pci_conf_read_16(pci_fun_t *, int);
     71extern uint32_t pci_conf_read_32(pci_fun_t *, int);
     72extern void pci_conf_write_8(pci_fun_t *, int, uint8_t);
     73extern void pci_conf_write_16(pci_fun_t *, int, uint16_t);
     74extern void pci_conf_write_32(pci_fun_t *, int, uint32_t);
    6875
    69 extern void pci_bus_scan(device_t *, int);
     76extern void pci_add_range(pci_fun_t *, uint64_t, size_t, bool);
     77extern int pci_read_bar(pci_fun_t *, int);
     78extern void pci_read_interrupt(pci_fun_t *);
     79extern void pci_add_interrupt(pci_fun_t *, int);
    7080
    71 extern pci_fun_data_t *create_pci_fun_data(void);
    72 extern void init_pci_fun_data(pci_fun_data_t *, int, int, int);
    73 extern void delete_pci_fun_data(pci_fun_data_t *);
    74 extern void create_pci_fun_name(function_t *);
     81extern pci_fun_t *pci_fun_new(void);
     82extern void pci_fun_init(pci_fun_t *, int, int, int);
     83extern void pci_fun_delete(pci_fun_t *);
     84extern void pci_fun_create_name(pci_fun_t *);
    7585
    76 extern bool pci_alloc_resource_list(function_t *);
    77 extern void pci_clean_resource_list(function_t *);
     86extern void pci_bus_scan(pci_bus_t *, int);
    7887
    79 extern void pci_read_bars(function_t *);
     88extern bool pci_alloc_resource_list(pci_fun_t *);
     89extern void pci_clean_resource_list(pci_fun_t *);
     90
     91extern void pci_read_bars(pci_fun_t *);
    8092extern size_t pci_bar_mask_to_size(uint32_t);
    8193
  • uspace/drv/root/root.c

    r8b1e15ac r68414f4a  
    22 * Copyright (c) 2010 Lenka Trochtova
    33 * Copyright (c) 2010 Vojtech Horky
     4 * Copyright (c) 2011 Jiri Svoboda
    45 * All rights reserved.
    56 *
     
    5556#define NAME "root"
    5657
    57 #define PLATFORM_DEVICE_NAME "hw"
    58 #define PLATFORM_DEVICE_MATCH_ID_FMT "platform/%s"
    59 #define PLATFORM_DEVICE_MATCH_SCORE 100
     58#define PLATFORM_FUN_NAME "hw"
     59#define PLATFORM_FUN_MATCH_ID_FMT "platform/%s"
     60#define PLATFORM_FUN_MATCH_SCORE 100
    6061
    61 #define VIRTUAL_DEVICE_NAME "virt"
    62 #define VIRTUAL_DEVICE_MATCH_ID "rootvirt"
    63 #define VIRTUAL_DEVICE_MATCH_SCORE 100
     62#define VIRTUAL_FUN_NAME "virt"
     63#define VIRTUAL_FUN_MATCH_ID "rootvirt"
     64#define VIRTUAL_FUN_MATCH_SCORE 100
    6465
    6566static int root_add_device(device_t *dev);
     
    7677};
    7778
    78 /** Create the device which represents the root of virtual device tree.
     79/** Create the function which represents the root of virtual device tree.
    7980 *
    80  * @param parent Parent of the newly created device.
    81  * @return Error code.
     81 * @param dev   Device
     82 * @return      EOK on success or negative error code
    8283 */
    83 static int add_virtual_root_child(device_t *parent)
     84static int add_virtual_root_fun(device_t *dev)
    8485{
    85         printf(NAME ": adding new child for virtual devices.\n");
    86         printf(NAME ":   device node is `%s' (%d %s)\n", VIRTUAL_DEVICE_NAME,
    87             VIRTUAL_DEVICE_MATCH_SCORE, VIRTUAL_DEVICE_MATCH_ID);
     86        printf(NAME ": adding new function for virtual devices.\n");
     87        printf(NAME ":   function node is `%s' (%d %s)\n", VIRTUAL_FUN_NAME,
     88            VIRTUAL_FUN_MATCH_SCORE, VIRTUAL_FUN_MATCH_ID);
    8889
    89         int res = register_function_wrapper(parent, VIRTUAL_DEVICE_NAME,
    90             VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE);
     90        int res = register_function_wrapper(dev, VIRTUAL_FUN_NAME,
     91            VIRTUAL_FUN_MATCH_ID, VIRTUAL_FUN_MATCH_SCORE);
    9192
    9293        return res;
    9394}
    9495
    95 /** Create the device which represents the root of HW device tree.
     96/** Create the function which represents the root of HW device tree.
    9697 *
    97  * @param parent        Parent of the newly created device.
    98  * @return 0 on success, negative error number otherwise.
     98 * @param dev   Device
     99 * @return      EOK on success or negative error code
    99100 */
    100 static int add_platform_child(device_t *parent)
     101static int add_platform_fun(device_t *dev)
    101102{
    102103        char *match_id;
     
    106107
    107108        /* Get platform name from sysinfo. */
    108 
    109109        platform = sysinfo_get_data("platform", &platform_size);
    110110        if (platform == NULL) {
     
    123123
    124124        /* Construct match ID. */
    125 
    126         if (asprintf(&match_id, PLATFORM_DEVICE_MATCH_ID_FMT, platform) == -1) {
     125        if (asprintf(&match_id, PLATFORM_FUN_MATCH_ID_FMT, platform) == -1) {
    127126                printf(NAME ": Memory allocation failed.\n");
    128127                return ENOMEM;
    129128        }
    130129
    131         /* Add child. */
     130        /* Add function. */
     131        printf(NAME ": adding platform function\n");
     132        printf(NAME ":   function node is `%s' (%d %s)\n", PLATFORM_FUN_NAME,
     133            PLATFORM_FUN_MATCH_SCORE, match_id);
    132134
    133         printf(NAME ": adding new child for platform device.\n");
    134         printf(NAME ":   device node is `%s' (%d %s)\n", PLATFORM_DEVICE_NAME,
    135             PLATFORM_DEVICE_MATCH_SCORE, match_id);
    136 
    137         res = register_function_wrapper(parent, PLATFORM_DEVICE_NAME,
    138             match_id, PLATFORM_DEVICE_MATCH_SCORE);
     135        res = register_function_wrapper(dev, PLATFORM_FUN_NAME,
     136            match_id, PLATFORM_FUN_MATCH_SCORE);
    139137
    140138        return res;
     
    156154         * vital for the system.
    157155         */
    158         add_virtual_root_child(dev);
     156        add_virtual_root_fun(dev);
    159157
    160158        /* Register root device's children. */
    161         int res = add_platform_child(dev);
     159        int res = add_platform_fun(dev);
    162160        if (EOK != res)
    163161                printf(NAME ": failed to add child device for platform.\n");
  • uspace/drv/rootpc/rootpc.c

    r8b1e15ac r68414f4a  
    5555#define NAME "rootpc"
    5656
    57 typedef struct rootpc_fun_data {
     57/** Obtain function soft-state from DDF function node */
     58#define ROOTPC_FUN(fnode) ((rootpc_fun_t *) (fnode)->driver_data)
     59
     60typedef struct rootpc_fun {
    5861        hw_resource_list_t hw_resources;
    59 } rootpc_fun_data_t;
     62} rootpc_fun_t;
    6063
    6164static int rootpc_add_device(device_t *dev);
     
    8285};
    8386
    84 static rootpc_fun_data_t pci_data = {
     87static rootpc_fun_t pci_data = {
    8588        .hw_resources = {
    8689                1,
     
    8992};
    9093
    91 static hw_resource_list_t *rootpc_get_fun_resources(function_t *fun)
    92 {
    93         rootpc_fun_data_t *data;
    94        
    95         data = (rootpc_fun_data_t *) fun->driver_data;
    96         if (NULL == data)
    97                 return NULL;
    98        
    99         return &data->hw_resources;
    100 }
    101 
    102 static bool rootpc_enable_fun_interrupt(function_t *fun)
     94static hw_resource_list_t *rootpc_get_resources(function_t *fnode)
     95{
     96        rootpc_fun_t *fun = ROOTPC_FUN(fnode);
     97       
     98        assert(fun != NULL);
     99        return &fun->hw_resources;
     100}
     101
     102static bool rootpc_enable_interrupt(function_t *fun)
    103103{
    104104        /* TODO */
     
    108108
    109109static hw_res_ops_t fun_hw_res_ops = {
    110         &rootpc_get_fun_resources,
    111         &rootpc_enable_fun_interrupt
     110        &rootpc_get_resources,
     111        &rootpc_enable_interrupt
    112112};
    113113
     
    116116
    117117static bool
    118 rootpc_add_fun(device_t *parent, const char *name, const char *str_match_id,
    119     rootpc_fun_data_t *drv_data)
     118rootpc_add_fun(device_t *dev, const char *name, const char *str_match_id,
     119    rootpc_fun_t *fun)
    120120{
    121121        printf(NAME ": adding new function '%s'.\n", name);
    122122       
    123         function_t *fun = NULL;
     123        function_t *fnode = NULL;
    124124        match_id_t *match_id = NULL;
    125125       
    126126        /* Create new device. */
    127         fun = create_function();
    128         if (fun == NULL)
     127        fnode = create_function();
     128        if (fnode == NULL)
    129129                goto failure;
    130130       
    131         fun->name = name;
    132         fun->driver_data = drv_data;
    133         fun->ftype = fun_inner;
     131        fnode->name = name;
     132        fnode->driver_data = fun;
     133        fnode->ftype = fun_inner;
    134134       
    135135        /* Initialize match id list */
    136136        match_id = create_match_id();
    137         if (NULL == match_id)
     137        if (match_id == NULL)
    138138                goto failure;
    139139       
    140140        match_id->id = str_match_id;
    141141        match_id->score = 100;
    142         add_match_id(&fun->match_ids, match_id);
     142        add_match_id(&fnode->match_ids, match_id);
    143143       
    144144        /* Set provided operations to the device. */
    145         fun->ops = &rootpc_fun_ops;
     145        fnode->ops = &rootpc_fun_ops;
    146146       
    147147        /* Register function. */
    148         if (EOK != register_function(fun, parent))
     148        if (register_function(fnode, dev) != EOK)
    149149                goto failure;
    150         printf(NAME ": registered function handle = %u\n", fun->handle);
     150        printf(NAME ": registered function handle = %u\n", fnode->handle);
    151151       
    152152        return true;
    153153       
    154154failure:
    155         if (NULL != match_id)
     155        if (match_id != NULL)
    156156                match_id->id = NULL;
    157157       
    158         if (NULL != fun) {
    159                 fun->name = NULL;
    160                 delete_function(fun);
     158        if (fnode != NULL) {
     159                fnode->name = NULL;
     160                delete_function(fnode);
    161161        }
    162162       
  • uspace/drv/rootvirt/rootvirt.c

    r8b1e15ac r68414f4a  
    6161};
    6262
    63 static int add_device(device_t *dev);
     63static int rootvirt_add_device(device_t *dev);
    6464
    6565static driver_ops_t rootvirt_ops = {
    66         .add_device = &add_device
     66        .add_device = &rootvirt_add_device
    6767};
    6868
     
    7878 * @return              EOK on success or negative error code.
    7979 */
    80 static int add_child(device_t *vdev, virtual_function_t *vfun)
     80static int rootvirt_add_fun(device_t *vdev, virtual_function_t *vfun)
    8181{
    8282        printf(NAME ": registering function `%s' (match \"%s\")\n",
     
    9797}
    9898
    99 static int add_device(device_t *dev)
     99static int rootvirt_add_device(device_t *dev)
    100100{
    101101        static int instances = 0;
     
    117117        virtual_function_t *vfun = virtual_functions;
    118118        while (vfun->name != NULL) {
    119                 (void) add_child(dev, vfun);
     119                (void) rootvirt_add_fun(dev, vfun);
    120120                vfun++;
    121121        }
Note: See TracChangeset for help on using the changeset viewer.