Changeset 92574f4 in mainline for uspace/drv


Ignore:
Timestamp:
2011-02-24T12:03:27Z (15 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e7b7ebd5
Parents:
4837092 (diff), a80849c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merged development (changes in DDF, etc.).

Conflicts in uspace/drv/usbkbd/main.c

Location:
uspace/drv
Files:
31 added
34 edited
6 moved

Legend:

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

    r4837092 r92574f4  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4344#include <stdlib.h>
    4445#include <str.h>
     46#include <str_error.h>
    4547#include <ctype.h>
    4648#include <macros.h>
     
    5052#include <sys/stat.h>
    5153
    52 #include <driver.h>
     54#include <ddf/driver.h>
    5355#include <ops/hw_res.h>
    5456
     
    5860
    5961#define NAME "isa"
    60 #define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev"
     62#define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
     63
     64/** Obtain soft-state pointer from function node pointer */
     65#define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data))
    6166
    6267#define ISA_MAX_HW_RES 4
    6368
    64 typedef struct isa_child_data {
     69typedef struct isa_fun {
     70        ddf_fun_t *fnode;
    6571        hw_resource_list_t hw_resources;
    66 } isa_child_data_t;
    67 
    68 static hw_resource_list_t *isa_get_child_resources(device_t *dev)
    69 {
    70         isa_child_data_t *dev_data;
    71 
    72         dev_data = (isa_child_data_t *)dev->driver_data;
    73         if (dev_data == NULL)
    74                 return NULL;
    75 
    76         return &dev_data->hw_resources;
    77 }
    78 
    79 static bool isa_enable_child_interrupt(device_t *dev)
     72} isa_fun_t;
     73
     74static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
     75{
     76        isa_fun_t *fun = ISA_FUN(fnode);
     77        assert(fun != NULL);
     78
     79        return &fun->hw_resources;
     80}
     81
     82static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
    8083{
    8184        // TODO
     
    8487}
    8588
    86 static hw_res_ops_t isa_child_hw_res_ops = {
    87         &isa_get_child_resources,
    88         &isa_enable_child_interrupt
     89static hw_res_ops_t isa_fun_hw_res_ops = {
     90        &isa_get_fun_resources,
     91        &isa_enable_fun_interrupt
    8992};
    9093
    91 static device_ops_t isa_child_dev_ops;
    92 
    93 static int isa_add_device(device_t *dev);
     94static ddf_dev_ops_t isa_fun_ops;
     95
     96static int isa_add_device(ddf_dev_t *dev);
    9497
    9598/** The isa device driver's standard operations */
     
    104107};
    105108
    106 
    107 static isa_child_data_t *create_isa_child_data()
    108 {
    109         isa_child_data_t *data;
    110 
    111         data = (isa_child_data_t *) malloc(sizeof(isa_child_data_t));
    112         if (data != NULL)
    113                 memset(data, 0, sizeof(isa_child_data_t));
    114 
    115         return data;
    116 }
    117 
    118 static device_t *create_isa_child_dev()
    119 {
    120         device_t *dev = create_device();
    121         if (dev == NULL)
     109static isa_fun_t *isa_fun_create(ddf_dev_t *dev, const char *name)
     110{
     111        isa_fun_t *fun = calloc(1, sizeof(isa_fun_t));
     112        if (fun == NULL)
    122113                return NULL;
    123114
    124         isa_child_data_t *data = create_isa_child_data();
    125         if (data == NULL) {
    126                 delete_device(dev);
     115        ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);
     116        if (fnode == NULL) {
     117                free(fun);
    127118                return NULL;
    128119        }
    129120
    130         dev->driver_data = data;
    131         return dev;
    132 }
    133 
    134 static char *read_dev_conf(const char *conf_path)
     121        fun->fnode = fnode;
     122        fnode->driver_data = fun;
     123        return fun;
     124}
     125
     126static char *fun_conf_read(const char *conf_path)
    135127{
    136128        bool suc = false;
     
    151143        lseek(fd, 0, SEEK_SET);
    152144        if (len == 0) {
    153                 printf(NAME ": read_dev_conf error: configuration file '%s' "
     145                printf(NAME ": fun_conf_read error: configuration file '%s' "
    154146                    "is empty.\n", conf_path);
    155147                goto cleanup;
     
    158150        buf = malloc(len + 1);
    159151        if (buf == NULL) {
    160                 printf(NAME ": read_dev_conf error: memory allocation failed.\n");
     152                printf(NAME ": fun_conf_read error: memory allocation failed.\n");
    161153                goto cleanup;
    162154        }
    163155
    164156        if (0 >= read(fd, buf, len)) {
    165                 printf(NAME ": read_dev_conf error: unable to read file '%s'.\n",
     157                printf(NAME ": fun_conf_read error: unable to read file '%s'.\n",
    166158                    conf_path);
    167159                goto cleanup;
     
    249241}
    250242
    251 static void isa_child_set_irq(device_t *dev, int irq)
    252 {
    253         isa_child_data_t *data = (isa_child_data_t *)dev->driver_data;
    254 
    255         size_t count = data->hw_resources.count;
    256         hw_resource_t *resources = data->hw_resources.resources;
     243static void isa_fun_set_irq(isa_fun_t *fun, int irq)
     244{
     245        size_t count = fun->hw_resources.count;
     246        hw_resource_t *resources = fun->hw_resources.resources;
    257247
    258248        if (count < ISA_MAX_HW_RES) {
     
    260250                resources[count].res.interrupt.irq = irq;
    261251
    262                 data->hw_resources.count++;
    263 
    264                 printf(NAME ": added irq 0x%x to device %s\n", irq, dev->name);
    265         }
    266 }
    267 
    268 static void isa_child_set_io_range(device_t *dev, size_t addr, size_t len)
    269 {
    270         isa_child_data_t *data = (isa_child_data_t *)dev->driver_data;
    271 
    272         size_t count = data->hw_resources.count;
    273         hw_resource_t *resources = data->hw_resources.resources;
     252                fun->hw_resources.count++;
     253
     254                printf(NAME ": added irq 0x%x to function %s\n", irq,
     255                    fun->fnode->name);
     256        }
     257}
     258
     259static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
     260{
     261        size_t count = fun->hw_resources.count;
     262        hw_resource_t *resources = fun->hw_resources.resources;
    274263
    275264        if (count < ISA_MAX_HW_RES) {
     
    279268                resources[count].res.io_range.endianness = LITTLE_ENDIAN;
    280269
    281                 data->hw_resources.count++;
     270                fun->hw_resources.count++;
    282271
    283272                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
    284                     "device %s\n", (unsigned int) addr, (unsigned int) len,
    285                     dev->name);
    286         }
    287 }
    288 
    289 static void get_dev_irq(device_t *dev, char *val)
     273                    "function %s\n", (unsigned int) addr, (unsigned int) len,
     274                    fun->fnode->name);
     275        }
     276}
     277
     278static void fun_parse_irq(isa_fun_t *fun, char *val)
    290279{
    291280        int irq = 0;
    292281        char *end = NULL;
    293282
    294         val = skip_spaces(val); 
     283        val = skip_spaces(val);
    295284        irq = (int)strtol(val, &end, 0x10);
    296285
    297286        if (val != end)
    298                 isa_child_set_irq(dev, irq);
    299 }
    300 
    301 static void get_dev_io_range(device_t *dev, char *val)
     287                isa_fun_set_irq(fun, irq);
     288}
     289
     290static void fun_parse_io_range(isa_fun_t *fun, char *val)
    302291{
    303292        size_t addr, len;
    304293        char *end = NULL;
    305294
    306         val = skip_spaces(val); 
     295        val = skip_spaces(val);
    307296        addr = strtol(val, &end, 0x10);
    308297
     
    310299                return;
    311300
    312         val = skip_spaces(end); 
     301        val = skip_spaces(end);
    313302        len = strtol(val, &end, 0x10);
    314303
     
    316305                return;
    317306
    318         isa_child_set_io_range(dev, addr, len);
     307        isa_fun_set_io_range(fun, addr, len);
    319308}
    320309
     
    331320}
    332321
    333 static void get_dev_match_id(device_t *dev, char *val)
     322static void fun_parse_match_id(isa_fun_t *fun, char *val)
    334323{
    335324        char *id = NULL;
    336325        int score = 0;
    337326        char *end = NULL;
    338 
    339         val = skip_spaces(val);
     327        int rc;
     328
     329        val = skip_spaces(val);
    340330
    341331        score = (int)strtol(val, &end, 10);
    342332        if (val == end) {
    343333                printf(NAME " : error - could not read match score for "
    344                     "device %s.\n", dev->name);
     334                    "function %s.\n", fun->fnode->name);
    345335                return;
    346336        }
    347337
    348         match_id_t *match_id = create_match_id();
    349         if (match_id == NULL) {
    350                 printf(NAME " : failed to allocate match id for device %s.\n",
    351                     dev->name);
    352                 return;
    353         }
    354 
    355         val = skip_spaces(end);
     338        val = skip_spaces(end);
    356339        get_match_id(&id, val);
    357340        if (id == NULL) {
    358341                printf(NAME " : error - could not read match id for "
    359                     "device %s.\n", dev->name);
    360                 delete_match_id(match_id);
     342                    "function %s.\n", fun->fnode->name);
    361343                return;
    362344        }
    363345
    364         match_id->id = id;
    365         match_id->score = score;
    366 
    367         printf(NAME ": adding match id '%s' with score %d to device %s\n", id,
    368             score, dev->name);
    369         add_match_id(&dev->match_ids, match_id);
    370 }
    371 
    372 static bool read_dev_prop(device_t *dev, char *line, const char *prop,
    373     void (*read_fn)(device_t *, char *))
     346        printf(NAME ": adding match id '%s' with score %d to function %s\n", id,
     347            score, fun->fnode->name);
     348
     349        rc = ddf_fun_add_match_id(fun->fnode, id, score);
     350        if (rc != EOK)
     351                printf(NAME ": error adding match ID: %s\n", str_error(rc));
     352}
     353
     354static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
     355    void (*read_fn)(isa_fun_t *, char *))
    374356{
    375357        size_t proplen = str_size(prop);
     
    378360                line += proplen;
    379361                line = skip_spaces(line);
    380                 (*read_fn)(dev, line);
     362                (*read_fn)(fun, line);
    381363
    382364                return true;
     
    386368}
    387369
    388 static void get_dev_prop(device_t *dev, char *line)
     370static void fun_prop_parse(isa_fun_t *fun, char *line)
    389371{
    390372        /* Skip leading spaces. */
    391373        line = skip_spaces(line);
    392374
    393         if (!read_dev_prop(dev, line, "io_range", &get_dev_io_range) &&
    394             !read_dev_prop(dev, line, "irq", &get_dev_irq) &&
    395             !read_dev_prop(dev, line, "match", &get_dev_match_id))
     375        if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) &&
     376            !prop_parse(fun, line, "irq", &fun_parse_irq) &&
     377            !prop_parse(fun, line, "match", &fun_parse_match_id))
    396378        {
    397379            printf(NAME " error undefined device property at line '%s'\n",
     
    400382}
    401383
    402 static void child_alloc_hw_res(device_t *dev)
    403 {
    404         isa_child_data_t *data = (isa_child_data_t *)dev->driver_data;
    405         data->hw_resources.resources =
     384static void fun_hw_res_alloc(isa_fun_t *fun)
     385{
     386        fun->hw_resources.resources =
    406387            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    407388}
    408389
    409 static char *read_isa_dev_info(char *dev_conf, device_t *parent)
     390static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev)
    410391{
    411392        char *line;
    412         char *dev_name = NULL;
     393        char *fun_name = NULL;
    413394
    414395        /* Skip empty lines. */
    415396        while (true) {
    416                 line = str_get_line(dev_conf, &dev_conf);
     397                line = str_get_line(fun_conf, &fun_conf);
    417398
    418399                if (line == NULL) {
     
    426407
    427408        /* Get device name. */
    428         dev_name = get_device_name(line);
    429         if (dev_name == NULL)
     409        fun_name = get_device_name(line);
     410        if (fun_name == NULL)
    430411                return NULL;
    431412
    432         device_t *dev = create_isa_child_dev();
    433         if (dev == NULL) {
    434                 free(dev_name);
     413        isa_fun_t *fun = isa_fun_create(dev, fun_name);
     414        if (fun == NULL) {
     415                free(fun_name);
    435416                return NULL;
    436417        }
    437418
    438         dev->name = dev_name;
    439 
    440419        /* Allocate buffer for the list of hardware resources of the device. */
    441         child_alloc_hw_res(dev);
     420        fun_hw_res_alloc(fun);
    442421
    443422        /* Get properties of the device (match ids, irq and io range). */
    444423        while (true) {
    445                 line = str_get_line(dev_conf, &dev_conf);
     424                line = str_get_line(fun_conf, &fun_conf);
    446425
    447426                if (line_empty(line)) {
     
    454433                 * and store it in the device structure.
    455434                 */
    456                 get_dev_prop(dev, line);
    457 
    458                 //printf(NAME ": next line ='%s'\n", dev_conf);
    459                 //printf(NAME ": current line ='%s'\n", line);
     435                fun_prop_parse(fun, line);
    460436        }
    461437
    462438        /* Set device operations to the device. */
    463         dev->ops = &isa_child_dev_ops;
    464 
    465         printf(NAME ": child_device_register(dev, parent); device is %s.\n",
    466             dev->name);
    467         child_device_register(dev, parent);
    468 
    469         return dev_conf;
    470 }
    471 
    472 static void parse_dev_conf(char *conf, device_t *parent)
     439        fun->fnode->ops = &isa_fun_ops;
     440
     441        printf(NAME ": Binding function %s.\n", fun->fnode->name);
     442
     443        /* XXX Handle error */
     444        (void) ddf_fun_bind(fun->fnode);
     445
     446        return fun_conf;
     447}
     448
     449static void fun_conf_parse(char *conf, ddf_dev_t *dev)
    473450{
    474451        while (conf != NULL && *conf != '\0') {
    475                 conf = read_isa_dev_info(conf, parent);
    476         }
    477 }
    478 
    479 static void add_legacy_children(device_t *parent)
    480 {
    481         char *dev_conf;
    482 
    483         dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH);
    484         if (dev_conf != NULL) {
    485                 parse_dev_conf(dev_conf, parent);
    486                 free(dev_conf);
    487         }
    488 }
    489 
    490 static int isa_add_device(device_t *dev)
     452                conf = isa_fun_read_info(conf, dev);
     453        }
     454}
     455
     456static void isa_functions_add(ddf_dev_t *dev)
     457{
     458        char *fun_conf;
     459
     460        fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
     461        if (fun_conf != NULL) {
     462                fun_conf_parse(fun_conf, dev);
     463                free(fun_conf);
     464        }
     465}
     466
     467static int isa_add_device(ddf_dev_t *dev)
    491468{
    492469        printf(NAME ": isa_add_device, device handle = %d\n",
    493470            (int) dev->handle);
    494471
    495         /* Add child devices. */
    496         add_legacy_children(dev);
    497         printf(NAME ": finished the enumeration of legacy devices\n");
     472        /* Make the bus device more visible. Does not do anything. */
     473        printf(NAME ": adding a 'ctl' function\n");
     474
     475        ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl");
     476        if (ctl == NULL) {
     477                printf(NAME ": Error creating control function.\n");
     478                return EXDEV;
     479        }
     480
     481        if (ddf_fun_bind(ctl) != EOK) {
     482                printf(NAME ": Error binding control function.\n");
     483                return EXDEV;
     484        }
     485
     486        /* Add functions as specified in the configuration file. */
     487        isa_functions_add(dev);
     488        printf(NAME ": finished the enumeration of legacy functions\n");
    498489
    499490        return EOK;
     
    502493static void isa_init()
    503494{
    504         isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_hw_res_ops;
     495        isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
    505496}
    506497
     
    509500        printf(NAME ": HelenOS ISA bus driver\n");
    510501        isa_init();
    511         return driver_main(&isa_driver);
     502        return ddf_driver_main(&isa_driver);
    512503}
    513504
     
    515506 * @}
    516507 */
    517  
  • uspace/drv/ns8250/ns8250.c

    r4837092 r92574f4  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    5253#include <libarch/ddi.h>
    5354
    54 #include <driver.h>
     55#include <ddf/driver.h>
     56#include <ddf/interrupt.h>
    5557#include <ops/char_dev.h>
    5658
     
    6769#define MAX_BAUD_RATE 115200
    6870#define DLAB_MASK (1 << 7)
     71
     72/** Obtain soft-state structure from function node */
     73#define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data))
     74
     75/** Obtain soft-state structure from device node */
     76#define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data))
    6977
    7078/** The number of bits of one data unit send by the serial port. */
     
    8593
    8694/** The driver data for the serial port devices. */
    87 typedef struct ns8250_dev_data {
     95typedef struct ns8250 {
     96        /** DDF device node */
     97        ddf_dev_t *dev;
     98        /** DDF function node */
     99        ddf_fun_t *fun;
    88100        /** Is there any client conntected to the device? */
    89101        bool client_connected;
     
    98110        /** The fibril mutex for synchronizing the access to the device. */
    99111        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);
     112} ns8250_t;
     113
     114/** Create per-device soft-state structure.
     115 *
     116 * @return      Pointer to soft-state structure.
     117 */
     118static ns8250_t *ns8250_new(void)
     119{
     120        ns8250_t *ns;
     121       
     122        ns = (ns8250_t *) calloc(1, sizeof(ns8250_t));
     123        if (ns == NULL)
     124                return NULL;
     125       
     126        fibril_mutex_initialize(&ns->mutex);
     127        return ns;
     128}
     129
     130/** Delete soft-state structure.
     131 *
     132 * @param ns    The driver data structure.
     133 */
     134static void ns8250_delete(ns8250_t *ns)
     135{
     136        assert(ns != NULL);
     137        free(ns);
    126138}
    127139
     
    171183/** Read data from the serial port device.
    172184 *
    173  * @param dev           The serial port device.
     185 * @param fun           The serial port function
    174186 * @param buf           The ouput buffer for read data.
    175187 * @param count         The number of bytes to be read.
     
    178190 *                      error number otherwise.
    179191 */
    180 static int ns8250_read(device_t *dev, char *buf, size_t count)
    181 {
     192static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count)
     193{
     194        ns8250_t *ns = NS8250(fun);
    182195        int ret = EOK;
    183         ns8250_dev_data_t *data = (ns8250_dev_data_t *) 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);
     196       
     197        fibril_mutex_lock(&ns->mutex);
     198        while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) {
     199                buf[ret] = (char)buf_pop_front(&ns->input_buffer);
    188200                ret++;
    189201        }
    190         fibril_mutex_unlock(&data->mutex);
     202        fibril_mutex_unlock(&ns->mutex);
    191203       
    192204        return ret;
     
    195207/** Write a character to the serial port.
    196208 *
    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);
     209 * @param ns            Serial port device
     210 * @param c             The character to be written
     211 */
     212static inline void ns8250_putchar(ns8250_t *ns, uint8_t c)
     213{
     214        fibril_mutex_lock(&ns->mutex);
     215        ns8250_write_8(ns->port, c);
     216        fibril_mutex_unlock(&ns->mutex);
    205217}
    206218
    207219/** Write data to the serial port.
    208220 *
    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.
    213  */
    214 static int ns8250_write(device_t *dev, char *buf, size_t count)
    215 {
    216         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     221 * @param fun           The serial port function
     222 * @param buf           The data to be written
     223 * @param count         The number of bytes to be written
     224 * @return              Zero on success
     225 */
     226static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count)
     227{
     228        ns8250_t *ns = NS8250(fun);
    217229        size_t idx;
    218230       
    219231        for (idx = 0; idx < count; idx++)
    220                 ns8250_putchar(data, (uint8_t) buf[idx]);
     232                ns8250_putchar(ns, (uint8_t) buf[idx]);
    221233       
    222234        return 0;
    223235}
    224236
    225 static device_ops_t ns8250_dev_ops;
     237static ddf_dev_ops_t ns8250_dev_ops;
    226238
    227239/** The character interface's callbacks. */
     
    231243};
    232244
    233 static int ns8250_add_device(device_t *dev);
     245static int ns8250_add_device(ddf_dev_t *dev);
    234246
    235247/** The serial port device driver's standard operations. */
     
    244256};
    245257
    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                 ipc_hangup(dev->parent_phone);
    259                 dev->parent_phone = 0;
     258/** Clean up the serial port soft-state
     259 *
     260 * @param ns            Serial port device
     261 */
     262static void ns8250_dev_cleanup(ns8250_t *ns)
     263{
     264        if (ns->dev->parent_phone > 0) {
     265                async_hangup(ns->dev->parent_phone);
     266                ns->dev->parent_phone = 0;
    260267        }
    261268}
     
    263270/** Enable the i/o ports of the device.
    264271 *
    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;
     272 * @param ns            Serial port device
     273 * @return              True on success, false otherwise
     274 */
     275static bool ns8250_pio_enable(ns8250_t *ns)
     276{
     277        printf(NAME ": ns8250_pio_enable %s\n", ns->dev->name);
    273278       
    274279        /* Gain control over port's registers. */
    275         if (pio_enable((void *)(uintptr_t) data->io_addr, REG_COUNT,
    276             (void **) &data->port)) {
     280        if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT,
     281            (void **) &ns->port)) {
    277282                printf(NAME ": error - cannot gain the port %#" PRIx32 " for device "
    278                     "%s.\n", data->io_addr, dev->name);
     283                    "%s.\n", ns->io_addr, ns->dev->name);
    279284                return false;
    280285        }
     
    285290/** Probe the serial port device for its presence.
    286291 *
    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;
     292 * @param ns            Serial port device
     293 * @return              True if the device is present, false otherwise
     294 */
     295static bool ns8250_dev_probe(ns8250_t *ns)
     296{
     297        printf(NAME ": ns8250_dev_probe %s\n", ns->dev->name);
     298       
     299        ioport8_t *port_addr = ns->port;
    296300        bool res = true;
    297301        uint8_t olddata;
     
    310314       
    311315        if (!res)
    312                 printf(NAME ": device %s is not present.\n", dev->name);
     316                printf(NAME ": device %s is not present.\n", ns->dev->name);
    313317       
    314318        return res;
     
    317321/** Initialize serial port device.
    318322 *
    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);
     323 * @param ns            Serial port device
     324 * @return              Zero on success, negative error number otherwise
     325 */
     326static int ns8250_dev_initialize(ns8250_t *ns)
     327{
     328        printf(NAME ": ns8250_dev_initialize %s\n", ns->dev->name);
    325329       
    326330        int ret = EOK;
     
    329333        memset(&hw_resources, 0, sizeof(hw_resource_list_t));
    330334       
    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        
    337335        /* Connect to the parent's driver. */
    338         dev->parent_phone = devman_parent_device_connect(dev->handle,
     336        ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle,
    339337            IPC_FLAG_BLOCKING);
    340         if (dev->parent_phone < 0) {
     338        if (ns->dev->parent_phone < 0) {
    341339                printf(NAME ": failed to connect to the parent driver of the "
    342                     "device %s.\n", dev->name);
    343                 ret = dev->parent_phone;
     340                    "device %s.\n", ns->dev->name);
     341                ret = ns->dev->parent_phone;
    344342                goto failed;
    345343        }
    346344       
    347345        /* Get hw resources. */
    348         ret = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
     346        ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources);
    349347        if (ret != EOK) {
    350348                printf(NAME ": failed to get hw resources for the device "
    351                     "%s.\n", dev->name);
     349                    "%s.\n", ns->dev->name);
    352350                goto failed;
    353351        }
     
    362360                switch (res->type) {
    363361                case INTERRUPT:
    364                         data->irq = res->res.interrupt.irq;
     362                        ns->irq = res->res.interrupt.irq;
    365363                        irq = true;
    366364                        printf(NAME ": the %s device was asigned irq = 0x%x.\n",
    367                             dev->name, data->irq);
     365                            ns->dev->name, ns->irq);
    368366                        break;
    369367                       
    370368                case IO_RANGE:
    371                         data->io_addr = res->res.io_range.address;
     369                        ns->io_addr = res->res.io_range.address;
    372370                        if (res->res.io_range.size < REG_COUNT) {
    373371                                printf(NAME ": i/o range assigned to the device "
    374                                     "%s is too small.\n", dev->name);
     372                                    "%s is too small.\n", ns->dev->name);
    375373                                ret = ELIMIT;
    376374                                goto failed;
     
    378376                        ioport = true;
    379377                        printf(NAME ": the %s device was asigned i/o address = "
    380                             "0x%x.\n", dev->name, data->io_addr);
     378                            "0x%x.\n", ns->dev->name, ns->io_addr);
    381379                        break;
    382380                       
     
    388386        if (!irq || !ioport) {
    389387                printf(NAME ": missing hw resource(s) for the device %s.\n",
    390                     dev->name);
     388                    ns->dev->name);
    391389                ret = ENOENT;
    392390                goto failed;
     
    397395       
    398396failed:
    399         ns8250_dev_cleanup(dev);
     397        ns8250_dev_cleanup(ns);
    400398        hw_res_clean_resource_list(&hw_resources);
    401399        return ret;
     
    404402/** Enable interrupts on the serial port device.
    405403 *
    406  * Interrupt when data is received.
     404 * Interrupt when data is received
    407405 *
    408406 * @param port          The base address of the serial port device's ports.
    409407 */
    410408static inline void ns8250_port_interrupts_enable(ioport8_t *port)
    411 {       
     409{
    412410        pio_write_8(port + 1, 0x1);     /* Interrupt when data received. */
    413411        pio_write_8(port + 4, 0xB);
     
    416414/** Disable interrupts on the serial port device.
    417415 *
    418  * @param port          The base address of the serial port device's ports.
     416 * @param port          The base address of the serial port device's ports
    419417 */
    420418static inline void ns8250_port_interrupts_disable(ioport8_t *port)
     
    425423/** Enable interrupts for the serial port device.
    426424 *
    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        
     425 * @param ns            Serial port device
     426 * @return              Zero on success, negative error number otherwise
     427 */
     428static int ns8250_interrupt_enable(ns8250_t *ns)
     429{
    434430        /* Enable interrupt on the serial port. */
    435         ns8250_port_interrupts_enable(data->port);
     431        ns8250_port_interrupts_enable(ns->port);
    436432       
    437433        return EOK;
     
    618614 * Set the default parameters of the serial communication.
    619615 *
    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;
     616 * @param ns            Serial port device
     617 */
     618static void ns8250_initialize_port(ns8250_t *ns)
     619{
     620        ioport8_t *port = ns->port;
    626621       
    627622        /* Disable interrupts. */
     
    643638 * buffer.
    644639 *
    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;
     640 * @param ns            Serial port device
     641 */
     642static void ns8250_read_from_device(ns8250_t *ns)
     643{
     644        ioport8_t *port = ns->port;
    651645        bool cont = true;
    652646       
    653647        while (cont) {
    654                 fibril_mutex_lock(&data->mutex);
     648                fibril_mutex_lock(&ns->mutex);
    655649               
    656650                cont = ns8250_received(port);
     
    658652                        uint8_t val = ns8250_read_8(port);
    659653                       
    660                         if (data->client_connected) {
    661                                 if (!buf_push_back(&data->input_buffer, val)) {
     654                        if (ns->client_connected) {
     655                                if (!buf_push_back(&ns->input_buffer, val)) {
    662656                                        printf(NAME ": buffer overflow on "
    663                                             "%s.\n", dev->name);
     657                                            "%s.\n", ns->dev->name);
    664658                                } else {
    665659                                        printf(NAME ": the character %c saved "
    666660                                            "to the buffer of %s.\n",
    667                                             val, dev->name);
     661                                            val, ns->dev->name);
    668662                                }
    669663                        }
    670664                }
    671665               
    672                 fibril_mutex_unlock(&data->mutex);
     666                fibril_mutex_unlock(&ns->mutex);
    673667                fibril_yield();
    674668        }
     
    682676 * @param dev           The serial port device.
    683677 */
    684 static inline void ns8250_interrupt_handler(device_t *dev, ipc_callid_t iid,
     678static inline void ns8250_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid,
    685679    ipc_call_t *icall)
    686680{
    687         ns8250_read_from_device(dev);
     681        ns8250_read_from_device(NS8250_FROM_DEV(dev));
    688682}
    689683
    690684/** Register the interrupt handler for the device.
    691685 *
     686 * @param ns            Serial port device
     687 */
     688static inline int ns8250_register_interrupt_handler(ns8250_t *ns)
     689{
     690        return register_interrupt_handler(ns->dev, ns->irq,
     691            ns8250_interrupt_handler, NULL);
     692}
     693
     694/** Unregister the interrupt handler for the device.
     695 *
     696 * @param ns            Serial port device
     697 */
     698static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns)
     699{
     700        return unregister_interrupt_handler(ns->dev, ns->irq);
     701}
     702
     703/** The add_device callback method of the serial port driver.
     704 *
     705 * Probe and initialize the newly added device.
     706 *
    692707 * @param dev           The serial port device.
    693708 */
    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  */
    719 static int ns8250_add_device(device_t *dev)
    720 {
     709static int ns8250_add_device(ddf_dev_t *dev)
     710{
     711        ns8250_t *ns = NULL;
     712        ddf_fun_t *fun = NULL;
     713        bool need_cleanup = false;
     714        int rc;
     715       
    721716        printf(NAME ": ns8250_add_device %s (handle = %d)\n",
    722717            dev->name, (int) dev->handle);
    723718       
    724         int res = ns8250_dev_initialize(dev);
    725         if (res != EOK)
    726                 return res;
    727        
    728         if (!ns8250_pio_enable(dev)) {
    729                 ns8250_dev_cleanup(dev);
    730                 return EADDRNOTAVAIL;
     719        /* Allocate soft-state for the device */
     720        ns = ns8250_new();
     721        if (ns == NULL) {
     722                rc = ENOMEM;
     723                goto fail;
     724        }
     725       
     726        ns->dev = dev;
     727        dev->driver_data = ns;
     728       
     729        rc = ns8250_dev_initialize(ns);
     730        if (rc != EOK)
     731                goto fail;
     732       
     733        need_cleanup = true;
     734       
     735        if (!ns8250_pio_enable(ns)) {
     736                rc = EADDRNOTAVAIL;
     737                goto fail;
    731738        }
    732739       
    733740        /* Find out whether the device is present. */
    734         if (!ns8250_dev_probe(dev)) {
    735                 ns8250_dev_cleanup(dev);
    736                 return ENOENT;
     741        if (!ns8250_dev_probe(ns)) {
     742                rc = ENOENT;
     743                goto fail;
    737744        }
    738745       
    739746        /* Serial port initialization (baud rate etc.). */
    740         ns8250_initialize_port(dev);
     747        ns8250_initialize_port(ns);
    741748       
    742749        /* Register interrupt handler. */
    743         if (ns8250_register_interrupt_handler(dev) != EOK) {
     750        if (ns8250_register_interrupt_handler(ns) != EOK) {
    744751                printf(NAME ": failed to register interrupt handler.\n");
    745                 ns8250_dev_cleanup(dev);
    746                 return res;
     752                rc = EADDRNOTAVAIL;
     753                goto fail;
    747754        }
    748755       
    749756        /* Enable interrupt. */
    750         res = ns8250_interrupt_enable(dev);
    751         if (res != EOK) {
     757        rc = ns8250_interrupt_enable(ns);
     758        if (rc != EOK) {
    752759                printf(NAME ": failed to enable the interrupt. Error code = "
    753                     "%d.\n", res);
    754                 ns8250_dev_cleanup(dev);
    755                 ns8250_unregister_interrupt_handler(dev);
    756                 return res;
     760                    "%d.\n", rc);
     761                goto fail;
     762        }
     763       
     764        fun = ddf_fun_create(dev, fun_exposed, "a");
     765        if (fun == NULL) {
     766                printf(NAME ": error creating function.\n");
     767                goto fail;
    757768        }
    758769       
    759770        /* Set device operations. */
    760         dev->ops = &ns8250_dev_ops;
    761        
    762         add_device_to_class(dev, "serial");
     771        fun->ops = &ns8250_dev_ops;
     772        rc = ddf_fun_bind(fun);
     773        if (rc != EOK) {
     774                printf(NAME ": error binding function.\n");
     775                goto fail;
     776        }
     777
     778        ns->fun = fun;
     779       
     780        ddf_fun_add_to_class(fun, "serial");
    763781       
    764782        printf(NAME ": the %s device has been successfully initialized.\n",
     
    766784       
    767785        return EOK;
     786fail:
     787        if (fun != NULL)
     788                ddf_fun_destroy(fun);
     789        if (need_cleanup)
     790                ns8250_dev_cleanup(ns);
     791        if (ns != NULL)
     792                ns8250_delete(ns);
     793        return rc;
    768794}
    769795
     
    775801 * @param dev           The device.
    776802 */
    777 static int ns8250_open(device_t *dev)
    778 {
    779         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     803static int ns8250_open(ddf_fun_t *fun)
     804{
     805        ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
    780806        int res;
    781807       
     
    788814        }
    789815        fibril_mutex_unlock(&data->mutex);
    790 
     816       
    791817        return res;
    792818}
     
    799825 * @param dev           The device.
    800826 */
    801 static void ns8250_close(device_t *dev)
    802 {
    803         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     827static void ns8250_close(ddf_fun_t *fun)
     828{
     829        ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
    804830       
    805831        fibril_mutex_lock(&data->mutex);
     
    823849 */
    824850static void
    825 ns8250_get_props(device_t *dev, unsigned int *baud_rate, unsigned int *parity,
     851ns8250_get_props(ddf_dev_t *dev, unsigned int *baud_rate, unsigned int *parity,
    826852    unsigned int *word_length, unsigned int* stop_bits)
    827853{
    828         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     854        ns8250_t *data = (ns8250_t *) dev->driver_data;
    829855        ioport8_t *port = data->port;
    830856       
     
    850876 * @param stop_bits     The number of stop bits to be used.
    851877 */
    852 static int ns8250_set_props(device_t *dev, unsigned int baud_rate,
     878static int ns8250_set_props(ddf_dev_t *dev, unsigned int baud_rate,
    853879    unsigned int parity, unsigned int word_length, unsigned int stop_bits)
    854880{
     
    857883            stop_bits);
    858884       
    859         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     885        ns8250_t *data = (ns8250_t *) dev->driver_data;
    860886        ioport8_t *port = data->port;
    861887        int ret;
     
    877903 * Configure the parameters of the serial communication.
    878904 */
    879 static void ns8250_default_handler(device_t *dev, ipc_callid_t callid,
     905static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid,
    880906    ipc_call_t *call)
    881907{
     
    886912        switch (method) {
    887913        case SERIAL_GET_COM_PROPS:
    888                 ns8250_get_props(dev, &baud_rate, &parity, &word_length,
     914                ns8250_get_props(fun->dev, &baud_rate, &parity, &word_length,
    889915                    &stop_bits);
    890                 ipc_answer_4(callid, EOK, baud_rate, parity, word_length,
     916                async_answer_4(callid, EOK, baud_rate, parity, word_length,
    891917                    stop_bits);
    892918                break;
     
    897923                word_length = IPC_GET_ARG3(*call);
    898924                stop_bits = IPC_GET_ARG4(*call);
    899                 ret = ns8250_set_props(dev, baud_rate, parity, word_length,
     925                ret = ns8250_set_props(fun->dev, baud_rate, parity, word_length,
    900926                    stop_bits);
    901                 ipc_answer_0(callid, ret);
     927                async_answer_0(callid, ret);
    902928                break;
    903929               
    904930        default:
    905                 ipc_answer_0(callid, ENOTSUP);
     931                async_answer_0(callid, ENOTSUP);
    906932        }
    907933}
     
    925951        printf(NAME ": HelenOS serial port driver\n");
    926952        ns8250_init();
    927         return driver_main(&ns8250_driver);
     953        return ddf_driver_main(&ns8250_driver);
    928954}
    929955
  • uspace/drv/pciintel/pci.c

    r4837092 r92574f4  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4445#include <ctype.h>
    4546#include <macros.h>
    46 
    47 #include <driver.h>
     47#include <str_error.h>
     48
     49#include <ddf/driver.h>
    4850#include <devman.h>
    4951#include <ipc/devman.h>
    5052#include <ipc/dev_iface.h>
     53#include <ipc/irc.h>
     54#include <ipc/ns.h>
     55#include <ipc/services.h>
     56#include <sysinfo.h>
    5157#include <ops/hw_res.h>
    5258#include <device/hw_res.h>
     
    6167        ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
    6268
    63 static hw_resource_list_t *pciintel_get_child_resources(device_t *dev)
    64 {
    65         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    66        
    67         if (dev_data == NULL)
     69/** Obtain PCI function soft-state from DDF function node */
     70#define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
     71
     72/** Obtain PCI bus soft-state from DDF device node */
     73#define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
     74
     75/** Obtain PCI bus soft-state from function soft-state */
     76#define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
     77
     78static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
     79{
     80        pci_fun_t *fun = PCI_FUN(fnode);
     81       
     82        if (fun == NULL)
    6883                return NULL;
    69         return &dev_data->hw_resources;
    70 }
    71 
    72 static bool pciintel_enable_child_interrupt(device_t *dev)
    73 {
    74         /* TODO */
    75        
    76         return false;
    77 }
    78 
    79 static hw_res_ops_t pciintel_child_hw_res_ops = {
    80         &pciintel_get_child_resources,
    81         &pciintel_enable_child_interrupt
     84        return &fun->hw_resources;
     85}
     86
     87static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
     88{
     89        /* This is an old ugly way, copied from ne2000 driver */
     90        assert(fnode);
     91        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
     92
     93  sysarg_t apic;
     94  sysarg_t i8259;
     95        int irc_phone = -1;
     96        int irc_service = 0;
     97
     98  if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
     99    irc_service = SERVICE_APIC;
     100        } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
     101    irc_service = SERVICE_I8259;
     102        }
     103
     104  if (irc_service) {
     105    while (irc_phone < 0)
     106      irc_phone = service_connect_blocking(irc_service, 0, 0);
     107  } else {
     108                return false;
     109        }
     110
     111        size_t i;
     112  for (i = 0; i < dev_data->hw_resources.count; i++) {
     113                if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
     114                        int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
     115                        async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     116                }
     117        }
     118
     119        async_hangup(irc_phone);
     120        return true;
     121}
     122
     123static hw_res_ops_t pciintel_hw_res_ops = {
     124        &pciintel_get_resources,
     125        &pciintel_enable_interrupt
    82126};
    83127
    84 static device_ops_t pci_child_ops;
    85 
    86 static int pci_add_device(device_t *);
    87 
    88 /** The pci bus driver's standard operations. */
     128static ddf_dev_ops_t pci_fun_ops;
     129
     130static int pci_add_device(ddf_dev_t *);
     131
     132/** PCI bus driver standard operations */
    89133static driver_ops_t pci_ops = {
    90134        .add_device = &pci_add_device
    91135};
    92136
    93 /** The pci bus driver structure. */
     137/** PCI bus driver structure */
    94138static driver_t pci_driver = {
    95139        .name = NAME,
     
    97141};
    98142
    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(device_t *dev, int reg, uint8_t *buf, size_t len)
    125 {
    126         assert(dev->parent != NULL);
    127        
    128         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    129         pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;
    130        
    131         fibril_mutex_lock(&bus_data->conf_mutex);
     143static pci_bus_t *pci_bus_new(void)
     144{
     145        pci_bus_t *bus;
     146       
     147        bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t));
     148        if (bus == NULL)
     149                return NULL;
     150       
     151        fibril_mutex_initialize(&bus->conf_mutex);
     152        return bus;
     153}
     154
     155static void pci_bus_delete(pci_bus_t *bus)
     156{
     157        assert(bus != NULL);
     158        free(bus);
     159}
     160
     161static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     162{
     163        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     164       
     165        fibril_mutex_lock(&bus->conf_mutex);
    132166       
    133167        uint32_t conf_addr;
    134         conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_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);
     168        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     169        void *addr = bus->conf_data_port + (reg & 3);
     170       
     171        pio_write_32(bus->conf_addr_port, conf_addr);
    138172       
    139173        switch (len) {
     
    149183        }
    150184       
    151         fibril_mutex_unlock(&bus_data->conf_mutex);
    152 }
    153 
    154 static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len)
    155 {
    156         assert(dev->parent != NULL);
    157        
    158         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    159         pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;
    160        
    161         fibril_mutex_lock(&bus_data->conf_mutex);
     185        fibril_mutex_unlock(&bus->conf_mutex);
     186}
     187
     188static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     189{
     190        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     191       
     192        fibril_mutex_lock(&bus->conf_mutex);
    162193       
    163194        uint32_t conf_addr;
    164         conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_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);
     195        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     196        void *addr = bus->conf_data_port + (reg & 3);
     197       
     198        pio_write_32(bus->conf_addr_port, conf_addr);
    168199       
    169200        switch (len) {
     
    179210        }
    180211       
    181         fibril_mutex_unlock(&bus_data->conf_mutex);
    182 }
    183 
    184 uint8_t pci_conf_read_8(device_t *dev, int reg)
     212        fibril_mutex_unlock(&bus->conf_mutex);
     213}
     214
     215uint8_t pci_conf_read_8(pci_fun_t *fun, int reg)
    185216{
    186217        uint8_t res;
    187         pci_conf_read(dev, reg, &res, 1);
     218        pci_conf_read(fun, reg, &res, 1);
    188219        return res;
    189220}
    190221
    191 uint16_t pci_conf_read_16(device_t *dev, int reg)
     222uint16_t pci_conf_read_16(pci_fun_t *fun, int reg)
    192223{
    193224        uint16_t res;
    194         pci_conf_read(dev, reg, (uint8_t *) &res, 2);
     225        pci_conf_read(fun, reg, (uint8_t *) &res, 2);
    195226        return res;
    196227}
    197228
    198 uint32_t pci_conf_read_32(device_t *dev, int reg)
     229uint32_t pci_conf_read_32(pci_fun_t *fun, int reg)
    199230{
    200231        uint32_t res;
    201         pci_conf_read(dev, reg, (uint8_t *) &res, 4);
     232        pci_conf_read(fun, reg, (uint8_t *) &res, 4);
    202233        return res;
    203234}
    204235
    205 void pci_conf_write_8(device_t *dev, int reg, uint8_t val)
    206 {
    207         pci_conf_write(dev, reg, (uint8_t *) &val, 1);
    208 }
    209 
    210 void pci_conf_write_16(device_t *dev, int reg, uint16_t val)
    211 {
    212         pci_conf_write(dev, reg, (uint8_t *) &val, 2);
    213 }
    214 
    215 void pci_conf_write_32(device_t *dev, int reg, uint32_t val)
    216 {
    217         pci_conf_write(dev, reg, (uint8_t *) &val, 4);
    218 }
    219 
    220 void create_pci_match_ids(device_t *dev)
    221 {
    222         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    223         match_id_t *match_id = NULL;
     236void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val)
     237{
     238        pci_conf_write(fun, reg, (uint8_t *) &val, 1);
     239}
     240
     241void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val)
     242{
     243        pci_conf_write(fun, reg, (uint8_t *) &val, 2);
     244}
     245
     246void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val)
     247{
     248        pci_conf_write(fun, reg, (uint8_t *) &val, 4);
     249}
     250
     251void pci_fun_create_match_ids(pci_fun_t *fun)
     252{
    224253        char *match_id_str;
    225        
    226         match_id = create_match_id();
    227         if (match_id != NULL) {
    228                 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x",
    229                     dev_data->vendor_id, dev_data->device_id);
    230                 match_id->id = match_id_str;
    231                 match_id->score = 90;
    232                 add_match_id(&dev->match_ids, match_id);
    233         }
    234 
     254        int rc;
     255       
     256        asprintf(&match_id_str, "pci/ven=%04x&dev=%04x",
     257            fun->vendor_id, fun->device_id);
     258
     259        if (match_id_str == NULL) {
     260                printf(NAME ": out of memory creating match ID.\n");
     261                return;
     262        }
     263
     264        rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90);
     265        if (rc != EOK) {
     266                printf(NAME ": error adding match ID: %s\n",
     267                    str_error(rc));
     268        }
     269       
    235270        /* TODO add more ids (with subsys ids, using class id etc.) */
    236271}
    237272
    238 void
    239 pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io)
    240 {
    241         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    242         hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     273void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size,
     274    bool io)
     275{
     276        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    243277        hw_resource_t *hw_resources =  hw_res_list->resources;
    244278        size_t count = hw_res_list->count;
     
    265299 * address add it to the devices hw resource list.
    266300 *
    267  * @param dev   The pci device.
     301 * @param fun   PCI function
    268302 * @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.
     303 *              the device
     304 * @return      The addr the address of the BAR which should be read next
    271305 */
    272 int pci_read_bar(device_t *dev, int addr)
    273 {       
     306int pci_read_bar(pci_fun_t *fun, int addr)
     307{
    274308        /* Value of the BAR */
    275309        uint32_t val, mask;
     
    285319       
    286320        /* Get the value of the BAR. */
    287         val = pci_conf_read_32(dev, addr);
     321        val = pci_conf_read_32(fun, addr);
    288322       
    289323        io = (bool) (val & 1);
     
    305339       
    306340        /* Get the address mask. */
    307         pci_conf_write_32(dev, addr, 0xffffffff);
    308         mask = pci_conf_read_32(dev, addr);
     341        pci_conf_write_32(fun, addr, 0xffffffff);
     342        mask = pci_conf_read_32(fun, addr);
    309343       
    310344        /* Restore the original value. */
    311         pci_conf_write_32(dev, addr, val);
    312         val = pci_conf_read_32(dev, addr);
     345        pci_conf_write_32(fun, addr, val);
     346        val = pci_conf_read_32(fun, addr);
    313347       
    314348        range_size = pci_bar_mask_to_size(mask);
    315349       
    316350        if (addrw64) {
    317                 range_addr = ((uint64_t)pci_conf_read_32(dev, addr + 4) << 32) |
     351                range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) |
    318352                    (val & 0xfffffff0);
    319353        } else {
     
    322356       
    323357        if (range_addr != 0) {
    324                 printf(NAME ": device %s : ", dev->name);
     358                printf(NAME ": function %s : ", fun->fnode->name);
    325359                printf("address = %" PRIx64, range_addr);
    326360                printf(", size = %x\n", (unsigned int) range_size);
    327361        }
    328362       
    329         pci_add_range(dev, range_addr, range_size, io);
     363        pci_add_range(fun, range_addr, range_size, io);
    330364       
    331365        if (addrw64)
     
    335369}
    336370
    337 void pci_add_interrupt(device_t *dev, int irq)
    338 {
    339         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    340         hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     371void pci_add_interrupt(pci_fun_t *fun, int irq)
     372{
     373        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    341374        hw_resource_t *hw_resources = hw_res_list->resources;
    342375        size_t count = hw_res_list->count;
     
    350383        hw_res_list->count++;
    351384       
    352         printf(NAME ": device %s uses irq %x.\n", dev->name, irq);
    353 }
    354 
    355 void pci_read_interrupt(device_t *dev)
    356 {
    357         uint8_t irq = pci_conf_read_8(dev, PCI_BRIDGE_INT_LINE);
     385        printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq);
     386}
     387
     388void pci_read_interrupt(pci_fun_t *fun)
     389{
     390        uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
    358391        if (irq != 0xff)
    359                 pci_add_interrupt(dev, irq);
     392                pci_add_interrupt(fun, irq);
    360393}
    361394
    362395/** Enumerate (recursively) and register the devices connected to a pci bus.
    363396 *
    364  * @param parent        The host-to-pci bridge device.
    365  * @param bus_num       The bus number.
     397 * @param bus           Host-to-PCI bridge
     398 * @param bus_num       Bus number
    366399 */
    367 void pci_bus_scan(device_t *parent, int bus_num)
    368 {
    369         device_t *dev = create_device();
    370         pci_dev_data_t *dev_data = create_pci_dev_data();
    371         dev->driver_data = dev_data;
    372         dev->parent = parent;
     400void pci_bus_scan(pci_bus_t *bus, int bus_num)
     401{
     402        ddf_fun_t *fnode;
     403        pci_fun_t *fun;
    373404       
    374405        int child_bus = 0;
    375406        int dnum, fnum;
    376407        bool multi;
    377         uint8_t header_type;
     408        uint8_t header_type;
     409       
     410        fun = pci_fun_new(bus);
    378411       
    379412        for (dnum = 0; dnum < 32; dnum++) {
    380413                multi = true;
    381414                for (fnum = 0; multi && fnum < 8; fnum++) {
    382                         init_pci_dev_data(dev_data, bus_num, dnum, fnum);
    383                         dev_data->vendor_id = pci_conf_read_16(dev,
     415                        pci_fun_init(fun, bus_num, dnum, fnum);
     416                        fun->vendor_id = pci_conf_read_16(fun,
    384417                            PCI_VENDOR_ID);
    385                         dev_data->device_id = pci_conf_read_16(dev,
     418                        fun->device_id = pci_conf_read_16(fun,
    386419                            PCI_DEVICE_ID);
    387                         if (dev_data->vendor_id == 0xffff) {
     420                        if (fun->vendor_id == 0xffff) {
    388421                                /*
    389422                                 * The device is not present, go on scanning the
     
    396429                        }
    397430                       
    398                         header_type = pci_conf_read_8(dev, PCI_HEADER_TYPE);
     431                        header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE);
    399432                        if (fnum == 0) {
    400433                                /* Is the device multifunction? */
     
    404437                        header_type = header_type & 0x7F;
    405438                       
    406                         create_pci_dev_name(dev);
    407                        
    408                         pci_alloc_resource_list(dev);
    409                         pci_read_bars(dev);
    410                         pci_read_interrupt(dev);
    411                        
    412                         dev->ops = &pci_child_ops;
    413                        
    414                         printf(NAME ": adding new child device %s.\n",
    415                             dev->name);
    416                        
    417                         create_pci_match_ids(dev);
    418                        
    419                         if (child_device_register(dev, parent) != EOK) {
    420                                 pci_clean_resource_list(dev);
    421                                 clean_match_ids(&dev->match_ids);
    422                                 free((char *) dev->name);
    423                                 dev->name = NULL;
     439                        char *fun_name = pci_fun_create_name(fun);
     440                        if (fun_name == NULL) {
     441                                printf(NAME ": out of memory.\n");
     442                                return;
     443                        }
     444                       
     445                        fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
     446                        if (fnode == NULL) {
     447                                printf(NAME ": error creating function.\n");
     448                                return;
     449                        }
     450                       
     451                        free(fun_name);
     452                        fun->fnode = fnode;
     453                       
     454                        pci_alloc_resource_list(fun);
     455                        pci_read_bars(fun);
     456                        pci_read_interrupt(fun);
     457                       
     458                        fnode->ops = &pci_fun_ops;
     459                        fnode->driver_data = fun;
     460                       
     461                        printf(NAME ": adding new function %s.\n",
     462                            fnode->name);
     463                       
     464                        pci_fun_create_match_ids(fun);
     465                       
     466                        if (ddf_fun_bind(fnode) != EOK) {
     467                                pci_clean_resource_list(fun);
     468                                clean_match_ids(&fnode->match_ids);
     469                                free((char *) fnode->name);
     470                                fnode->name = NULL;
    424471                                continue;
    425472                        }
     
    427474                        if (header_type == PCI_HEADER_TYPE_BRIDGE ||
    428475                            header_type == PCI_HEADER_TYPE_CARDBUS) {
    429                                 child_bus = pci_conf_read_8(dev,
     476                                child_bus = pci_conf_read_8(fun,
    430477                                    PCI_BRIDGE_SEC_BUS_NUM);
    431478                                printf(NAME ": device is pci-to-pci bridge, "
    432479                                    "secondary bus number = %d.\n", bus_num);
    433480                                if (child_bus > bus_num)
    434                                         pci_bus_scan(parent, child_bus);
     481                                        pci_bus_scan(bus, child_bus);
    435482                        }
    436483                       
    437                         /* Alloc new aux. dev. structure. */
    438                         dev = create_device();
    439                         dev_data = create_pci_dev_data();
    440                         dev->driver_data = dev_data;
    441                         dev->parent = parent;
     484                        fun = pci_fun_new(bus);
    442485                }
    443486        }
    444487       
    445         if (dev_data->vendor_id == 0xffff) {
    446                 delete_device(dev);
    447                 /* Free the auxiliary device structure. */
    448                 delete_pci_dev_data(dev_data);
    449         }
    450 }
    451 
    452 static int pci_add_device(device_t *dev)
    453 {
     488        if (fun->vendor_id == 0xffff) {
     489                /* Free the auxiliary function structure. */
     490                pci_fun_delete(fun);
     491        }
     492}
     493
     494static int pci_add_device(ddf_dev_t *dnode)
     495{
     496        pci_bus_t *bus = NULL;
     497        ddf_fun_t *ctl = NULL;
     498        bool got_res = false;
    454499        int rc;
    455 
     500       
    456501        printf(NAME ": pci_add_device\n");
    457        
    458         pci_bus_data_t *bus_data = create_pci_bus_data();
    459         if (bus_data == NULL) {
     502        dnode->parent_phone = -1;
     503       
     504        bus = pci_bus_new();
     505        if (bus == NULL) {
    460506                printf(NAME ": pci_add_device allocation failed.\n");
    461                 return ENOMEM;
    462         }
    463        
    464         dev->parent_phone = devman_parent_device_connect(dev->handle,
     507                rc = ENOMEM;
     508                goto fail;
     509        }
     510        bus->dnode = dnode;
     511        dnode->driver_data = bus;
     512       
     513        dnode->parent_phone = devman_parent_device_connect(dnode->handle,
    465514            IPC_FLAG_BLOCKING);
    466         if (dev->parent_phone < 0) {
     515        if (dnode->parent_phone < 0) {
    467516                printf(NAME ": pci_add_device failed to connect to the "
    468517                    "parent's driver.\n");
    469                 delete_pci_bus_data(bus_data);
    470                 return dev->parent_phone;
     518                rc = dnode->parent_phone;
     519                goto fail;
    471520        }
    472521       
    473522        hw_resource_list_t hw_resources;
    474523       
    475         rc = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
     524        rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
    476525        if (rc != EOK) {
    477526                printf(NAME ": pci_add_device failed to get hw resources for "
    478527                    "the device.\n");
    479                 delete_pci_bus_data(bus_data);
    480                 ipc_hangup(dev->parent_phone);
    481                 return rc;
    482         }       
     528                goto fail;
     529        }
     530        got_res = true;
    483531       
    484532        printf(NAME ": conf_addr = %" PRIx64 ".\n",
     
    489537        assert(hw_resources.resources[0].res.io_range.size == 8);
    490538       
    491         bus_data->conf_io_addr =
     539        bus->conf_io_addr =
    492540            (uint32_t) hw_resources.resources[0].res.io_range.address;
    493541       
    494         if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8,
    495             &bus_data->conf_addr_port)) {
     542        if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
     543            &bus->conf_addr_port)) {
    496544                printf(NAME ": failed to enable configuration ports.\n");
    497                 delete_pci_bus_data(bus_data);
    498                 ipc_hangup(dev->parent_phone);
     545                rc = EADDRNOTAVAIL;
     546                goto fail;
     547        }
     548        bus->conf_data_port = (char *) bus->conf_addr_port + 4;
     549       
     550        /* Make the bus device more visible. It has no use yet. */
     551        printf(NAME ": adding a 'ctl' function\n");
     552       
     553        ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl");
     554        if (ctl == NULL) {
     555                printf(NAME ": error creating control function.\n");
     556                rc = ENOMEM;
     557                goto fail;
     558        }
     559       
     560        rc = ddf_fun_bind(ctl);
     561        if (rc != EOK) {
     562                printf(NAME ": error binding control function.\n");
     563                goto fail;
     564        }
     565       
     566        /* Enumerate functions. */
     567        printf(NAME ": scanning the bus\n");
     568        pci_bus_scan(bus, 0);
     569       
     570        hw_res_clean_resource_list(&hw_resources);
     571       
     572        return EOK;
     573       
     574fail:
     575        if (bus != NULL)
     576                pci_bus_delete(bus);
     577        if (dnode->parent_phone >= 0)
     578                async_hangup(dnode->parent_phone);
     579        if (got_res)
    499580                hw_res_clean_resource_list(&hw_resources);
    500                 return EADDRNOTAVAIL;
    501         }
    502         bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4;
    503        
    504         dev->driver_data = bus_data;
    505        
    506         /* Enumerate child devices. */
    507         printf(NAME ": scanning the bus\n");
    508         pci_bus_scan(dev, 0);
    509        
    510         hw_res_clean_resource_list(&hw_resources);
    511        
    512         return EOK;
     581        if (ctl != NULL)
     582                ddf_fun_destroy(ctl);
     583
     584        return rc;
    513585}
    514586
    515587static void pciintel_init(void)
    516588{
    517         pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops;
    518 }
    519 
    520 pci_dev_data_t *create_pci_dev_data(void)
    521 {
    522         pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t));
    523        
    524         if (res != NULL)
    525                 memset(res, 0, sizeof(pci_dev_data_t));
    526         return res;
    527 }
    528 
    529 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn)
    530 {
    531         dev_data->bus = bus;
    532         dev_data->dev = dev;
    533         dev_data->fn = fn;
    534 }
    535 
    536 void delete_pci_dev_data(pci_dev_data_t *dev_data)
    537 {
    538         if (dev_data != NULL) {
    539                 hw_res_clean_resource_list(&dev_data->hw_resources);
    540                 free(dev_data);
    541         }
    542 }
    543 
    544 void create_pci_dev_name(device_t *dev)
    545 {
    546         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
     589        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     590}
     591
     592pci_fun_t *pci_fun_new(pci_bus_t *bus)
     593{
     594        pci_fun_t *fun;
     595       
     596        fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
     597        if (fun == NULL)
     598                return NULL;
     599
     600        fun->busptr = bus;
     601        return fun;
     602}
     603
     604void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn)
     605{
     606        fun->bus = bus;
     607        fun->dev = dev;
     608        fun->fn = fn;
     609}
     610
     611void pci_fun_delete(pci_fun_t *fun)
     612{
     613        assert(fun != NULL);
     614        hw_res_clean_resource_list(&fun->hw_resources);
     615        free(fun);
     616}
     617
     618char *pci_fun_create_name(pci_fun_t *fun)
     619{
    547620        char *name = NULL;
    548621       
    549         asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev,
    550             dev_data->fn);
    551         dev->name = name;
    552 }
    553 
    554 bool pci_alloc_resource_list(device_t *dev)
    555 {
    556         pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
    557        
    558         dev_data->hw_resources.resources =
     622        asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev,
     623            fun->fn);
     624        return name;
     625}
     626
     627bool pci_alloc_resource_list(pci_fun_t *fun)
     628{
     629        fun->hw_resources.resources =
    559630            (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t));
    560         return dev_data->hw_resources.resources != NULL;
    561 }
    562 
    563 void pci_clean_resource_list(device_t *dev)
    564 {
    565         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    566        
    567         if (dev_data->hw_resources.resources != NULL) {
    568                 free(dev_data->hw_resources.resources);
    569                 dev_data->hw_resources.resources = NULL;
    570         }
    571 }
    572 
    573 /** Read the base address registers (BARs) of the device and adds the addresses
    574  * to its hw resource list.
     631        return fun->hw_resources.resources != NULL;
     632}
     633
     634void pci_clean_resource_list(pci_fun_t *fun)
     635{
     636        if (fun->hw_resources.resources != NULL) {
     637                free(fun->hw_resources.resources);
     638                fun->hw_resources.resources = NULL;
     639        }
     640}
     641
     642/** Read the base address registers (BARs) of the function and add the addresses
     643 * to its HW resource list.
    575644 *
    576  * @param dev the pci device.
     645 * @param fun   PCI function
    577646 */
    578 void pci_read_bars(device_t *dev)
     647void pci_read_bars(pci_fun_t *fun)
    579648{
    580649        /*
     
    585654       
    586655        while (addr <= PCI_BASE_ADDR_5)
    587                 addr = pci_read_bar(dev, addr);
     656                addr = pci_read_bar(fun, addr);
    588657}
    589658
     
    597666        printf(NAME ": HelenOS pci bus driver (intel method 1).\n");
    598667        pciintel_init();
    599         return driver_main(&pci_driver);
     668        return ddf_driver_main(&pci_driver);
    600669}
    601670
  • uspace/drv/pciintel/pci.h

    r4837092 r92574f4  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3637#define PCI_H_
    3738
    38 #include <stdlib.h>
    39 #include <driver.h>
    40 #include <malloc.h>
    41 
     39#include <ddf/driver.h>
    4240#include "pci_regs.h"
    4341
    4442#define PCI_MAX_HW_RES 8
    4543
    46 typedef struct pci_dev_data {
     44typedef struct pciintel_bus {
     45        /** DDF device node */
     46        ddf_dev_t *dnode;
     47        uint32_t conf_io_addr;
     48        void *conf_data_port;
     49        void *conf_addr_port;
     50        fibril_mutex_t conf_mutex;
     51} pci_bus_t;
     52
     53typedef struct pci_fun_data {
     54        pci_bus_t *busptr;
     55        ddf_fun_t *fnode;
     56
    4757        int bus;
    4858        int dev;
     
    5161        int device_id;
    5262        hw_resource_list_t hw_resources;
    53 } pci_dev_data_t;
     63} pci_fun_t;
    5464
    55 extern void create_pci_match_ids(device_t *);
     65extern void pci_fun_create_match_ids(pci_fun_t *);
    5666
    57 extern uint8_t pci_conf_read_8(device_t *, int);
    58 extern uint16_t pci_conf_read_16(device_t *, int);
    59 extern uint32_t pci_conf_read_32(device_t *, int);
    60 extern void pci_conf_write_8(device_t *, int, uint8_t);
    61 extern void pci_conf_write_16(device_t *, int, uint16_t);
    62 extern void pci_conf_write_32(device_t *, int, uint32_t);
     67extern uint8_t pci_conf_read_8(pci_fun_t *, int);
     68extern uint16_t pci_conf_read_16(pci_fun_t *, int);
     69extern uint32_t pci_conf_read_32(pci_fun_t *, int);
     70extern void pci_conf_write_8(pci_fun_t *, int, uint8_t);
     71extern void pci_conf_write_16(pci_fun_t *, int, uint16_t);
     72extern void pci_conf_write_32(pci_fun_t *, int, uint32_t);
    6373
    64 extern void pci_add_range(device_t *, uint64_t, size_t, bool);
    65 extern int pci_read_bar(device_t *, int);
    66 extern void pci_read_interrupt(device_t *);
    67 extern void pci_add_interrupt(device_t *, int);
     74extern void pci_add_range(pci_fun_t *, uint64_t, size_t, bool);
     75extern int pci_read_bar(pci_fun_t *, int);
     76extern void pci_read_interrupt(pci_fun_t *);
     77extern void pci_add_interrupt(pci_fun_t *, int);
    6878
    69 extern void pci_bus_scan(device_t *, int);
     79extern pci_fun_t *pci_fun_new(pci_bus_t *);
     80extern void pci_fun_init(pci_fun_t *, int, int, int);
     81extern void pci_fun_delete(pci_fun_t *);
     82extern char *pci_fun_create_name(pci_fun_t *);
    7083
    71 extern pci_dev_data_t *create_pci_dev_data(void);
    72 extern void init_pci_dev_data(pci_dev_data_t *, int, int, int);
    73 extern void delete_pci_dev_data(pci_dev_data_t *);
    74 extern void create_pci_dev_name(device_t *);
     84extern void pci_bus_scan(pci_bus_t *, int);
    7585
    76 extern bool pci_alloc_resource_list(device_t *);
    77 extern void pci_clean_resource_list(device_t *);
     86extern bool pci_alloc_resource_list(pci_fun_t *);
     87extern void pci_clean_resource_list(pci_fun_t *);
    7888
    79 extern void pci_read_bars(device_t *);
     89extern void pci_read_bars(pci_fun_t *);
    8090extern size_t pci_bar_mask_to_size(uint32_t);
    8191
  • uspace/drv/root/root.c

    r4837092 r92574f4  
    22 * Copyright (c) 2010 Lenka Trochtova
    33 * Copyright (c) 2010 Vojtech Horky
     4 * Copyright (c) 2011 Jiri Svoboda
    45 * All rights reserved.
    56 *
     
    4445#include <stdlib.h>
    4546#include <str.h>
     47#include <str_error.h>
    4648#include <ctype.h>
    4749#include <macros.h>
     
    4951#include <sysinfo.h>
    5052
    51 #include <driver.h>
     53#include <ddf/driver.h>
    5254#include <devman.h>
    5355#include <ipc/devman.h>
     
    5557#define NAME "root"
    5658
    57 #define PLATFORM_DEVICE_NAME "hw"
    58 #define PLATFORM_DEVICE_MATCH_ID_FMT "platform/%s"
    59 #define PLATFORM_DEVICE_MATCH_SCORE 100
    60 
    61 #define VIRTUAL_DEVICE_NAME "virt"
    62 #define VIRTUAL_DEVICE_MATCH_ID "rootvirt"
    63 #define VIRTUAL_DEVICE_MATCH_SCORE 100
    64 
    65 static int root_add_device(device_t *dev);
     59#define PLATFORM_FUN_NAME "hw"
     60#define PLATFORM_FUN_MATCH_ID_FMT "platform/%s"
     61#define PLATFORM_FUN_MATCH_SCORE 100
     62
     63#define VIRTUAL_FUN_NAME "virt"
     64#define VIRTUAL_FUN_MATCH_ID "rootvirt"
     65#define VIRTUAL_FUN_MATCH_SCORE 100
     66
     67static int root_add_device(ddf_dev_t *dev);
    6668
    6769/** The root device driver's standard operations. */
     
    7678};
    7779
    78 /** Create the device which represents the root of virtual device tree.
    79  *
    80  * @param parent Parent of the newly created device.
    81  * @return Error code.
    82  */
    83 static int add_virtual_root_child(device_t *parent)
    84 {
    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);
    88 
    89         int res = child_device_register_wrapper(parent, VIRTUAL_DEVICE_NAME,
    90             VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE,
    91             NULL);
    92 
    93         return res;
    94 }
    95 
    96 /** Create the device which represents the root of HW device tree.
    97  *
    98  * @param parent        Parent of the newly created device.
    99  * @return 0 on success, negative error number otherwise.
    100  */
    101 static int add_platform_child(device_t *parent)
     80/** Create the function which represents the root of virtual device tree.
     81 *
     82 * @param dev   Device
     83 * @return      EOK on success or negative error code
     84 */
     85static int add_virtual_root_fun(ddf_dev_t *dev)
     86{
     87        const char *name = VIRTUAL_FUN_NAME;
     88        ddf_fun_t *fun;
     89        int rc;
     90
     91        printf(NAME ": adding new function for virtual devices.\n");
     92        printf(NAME ":   function node is `%s' (%d %s)\n", name,
     93            VIRTUAL_FUN_MATCH_SCORE, VIRTUAL_FUN_MATCH_ID);
     94
     95        fun = ddf_fun_create(dev, fun_inner, name);
     96        if (fun == NULL) {
     97                printf(NAME ": error creating function %s\n", name);
     98                return ENOMEM;
     99        }
     100
     101        rc = ddf_fun_add_match_id(fun, VIRTUAL_FUN_MATCH_ID,
     102            VIRTUAL_FUN_MATCH_SCORE);
     103        if (rc != EOK) {
     104                printf(NAME ": error adding match IDs to function %s\n", name);
     105                ddf_fun_destroy(fun);
     106                return rc;
     107        }
     108
     109        rc = ddf_fun_bind(fun);
     110        if (rc != EOK) {
     111                printf(NAME ": error binding function %s: %s\n", name,
     112                    str_error(rc));
     113                ddf_fun_destroy(fun);
     114                return rc;
     115        }
     116
     117        return EOK;
     118}
     119
     120/** Create the function which represents the root of HW device tree.
     121 *
     122 * @param dev   Device
     123 * @return      EOK on success or negative error code
     124 */
     125static int add_platform_fun(ddf_dev_t *dev)
    102126{
    103127        char *match_id;
    104128        char *platform;
    105129        size_t platform_size;
    106         int res;
     130
     131        const char *name = PLATFORM_FUN_NAME;
     132        ddf_fun_t *fun;
     133        int rc;
    107134
    108135        /* Get platform name from sysinfo. */
    109 
    110136        platform = sysinfo_get_data("platform", &platform_size);
    111137        if (platform == NULL) {
     
    124150
    125151        /* Construct match ID. */
    126 
    127         if (asprintf(&match_id, PLATFORM_DEVICE_MATCH_ID_FMT, platform) == -1) {
     152        if (asprintf(&match_id, PLATFORM_FUN_MATCH_ID_FMT, platform) == -1) {
    128153                printf(NAME ": Memory allocation failed.\n");
    129154                return ENOMEM;
    130155        }
    131156
    132         /* Add child. */
    133 
    134         printf(NAME ": adding new child for platform device.\n");
    135         printf(NAME ":   device node is `%s' (%d %s)\n", PLATFORM_DEVICE_NAME,
    136             PLATFORM_DEVICE_MATCH_SCORE, match_id);
    137 
    138         res = child_device_register_wrapper(parent, PLATFORM_DEVICE_NAME,
    139             match_id, PLATFORM_DEVICE_MATCH_SCORE, NULL);
    140 
    141         return res;
     157        /* Add function. */
     158        printf(NAME ": adding platform function\n");
     159        printf(NAME ":   function node is `%s' (%d %s)\n", PLATFORM_FUN_NAME,
     160            PLATFORM_FUN_MATCH_SCORE, match_id);
     161
     162        fun = ddf_fun_create(dev, fun_inner, name);
     163        if (fun == NULL) {
     164                printf(NAME ": error creating function %s\n", name);
     165                return ENOMEM;
     166        }
     167
     168        rc = ddf_fun_add_match_id(fun, match_id, PLATFORM_FUN_MATCH_SCORE);
     169        if (rc != EOK) {
     170                printf(NAME ": error adding match IDs to function %s\n", name);
     171                ddf_fun_destroy(fun);
     172                return rc;
     173        }
     174
     175        rc = ddf_fun_bind(fun);
     176        if (rc != EOK) {
     177                printf(NAME ": error binding function %s: %s\n", name,
     178                    str_error(rc));
     179                ddf_fun_destroy(fun);
     180                return rc;
     181        }
     182
     183        return EOK;
    142184}
    143185
     
    147189 *                      of HW and pseudo devices).
    148190 */
    149 static int root_add_device(device_t *dev)
     191static int root_add_device(ddf_dev_t *dev)
    150192{
    151193        printf(NAME ": root_add_device, device handle=%" PRIun "\n",
    152194            dev->handle);
    153        
     195
    154196        /*
    155197         * Register virtual devices root.
     
    157199         * vital for the system.
    158200         */
    159         add_virtual_root_child(dev);
     201        add_virtual_root_fun(dev);
    160202
    161203        /* Register root device's children. */
    162         int res = add_platform_child(dev);
     204        int res = add_platform_fun(dev);
    163205        if (EOK != res)
    164206                printf(NAME ": failed to add child device for platform.\n");
    165        
     207
    166208        return res;
    167209}
     
    170212{
    171213        printf(NAME ": HelenOS root device driver\n");
    172         return driver_main(&root_driver);
     214        return ddf_driver_main(&root_driver);
    173215}
    174216
  • uspace/drv/rootpc/rootpc.c

    r4837092 r92574f4  
    4646#include <macros.h>
    4747
    48 #include <driver.h>
     48#include <ddf/driver.h>
    4949#include <devman.h>
    5050#include <ipc/devman.h>
     
    5555#define NAME "rootpc"
    5656
    57 typedef struct rootpc_child_dev_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_child_dev_data_t;
    60 
    61 static int rootpc_add_device(device_t *dev);
     62} rootpc_fun_t;
     63
     64static int rootpc_add_device(ddf_dev_t *dev);
    6265static void root_pc_init(void);
    6366
     
    8285};
    8386
    84 static rootpc_child_dev_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_child_resources(device_t *dev)
    92 {
    93         rootpc_child_dev_data_t *data;
    94        
    95         data = (rootpc_child_dev_data_t *) dev->driver_data;
    96         if (NULL == data)
    97                 return NULL;
    98        
    99         return &data->hw_resources;
    100 }
    101 
    102 static bool rootpc_enable_child_interrupt(device_t *dev)
     94static hw_resource_list_t *rootpc_get_resources(ddf_fun_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(ddf_fun_t *fun)
    103103{
    104104        /* TODO */
     
    107107}
    108108
    109 static hw_res_ops_t child_hw_res_ops = {
    110         &rootpc_get_child_resources,
    111         &rootpc_enable_child_interrupt
     109static hw_res_ops_t fun_hw_res_ops = {
     110        &rootpc_get_resources,
     111        &rootpc_enable_interrupt
    112112};
    113113
    114114/* Initialized in root_pc_init() function. */
    115 static device_ops_t rootpc_child_ops;
     115static ddf_dev_ops_t rootpc_fun_ops;
    116116
    117117static bool
    118 rootpc_add_child(device_t *parent, const char *name, const char *str_match_id,
    119     rootpc_child_dev_data_t *drv_data)
    120 {
    121         printf(NAME ": adding new child device '%s'.\n", name);
    122        
    123         device_t *child = NULL;
     118rootpc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id,
     119    rootpc_fun_t *fun)
     120{
     121        printf(NAME ": adding new function '%s'.\n", name);
     122       
     123        ddf_fun_t *fnode = NULL;
    124124        match_id_t *match_id = NULL;
    125125       
    126126        /* Create new device. */
    127         child = create_device();
    128         if (NULL == child)
     127        fnode = ddf_fun_create(dev, fun_inner, name);
     128        if (fnode == NULL)
    129129                goto failure;
    130130       
    131         child->name = name;
    132         child->driver_data = drv_data;
     131        fnode->driver_data = fun;
    133132       
    134133        /* Initialize match id list */
    135134        match_id = create_match_id();
    136         if (NULL == match_id)
     135        if (match_id == NULL)
    137136                goto failure;
    138137       
    139138        match_id->id = str_match_id;
    140139        match_id->score = 100;
    141         add_match_id(&child->match_ids, match_id);
     140        add_match_id(&fnode->match_ids, match_id);
    142141       
    143142        /* Set provided operations to the device. */
    144         child->ops = &rootpc_child_ops;
    145        
    146         /* Register child device. */
    147         if (EOK != child_device_register(child, parent))
     143        fnode->ops = &rootpc_fun_ops;
     144       
     145        /* Register function. */
     146        if (ddf_fun_bind(fnode) != EOK) {
     147                printf(NAME ": error binding function %s.\n", name);
    148148                goto failure;
     149        }
    149150       
    150151        return true;
    151152       
    152153failure:
    153         if (NULL != match_id)
     154        if (match_id != NULL)
    154155                match_id->id = NULL;
    155156       
    156         if (NULL != child) {
    157                 child->name = NULL;
    158                 delete_device(child);
    159         }
    160        
    161         printf(NAME ": failed to add child device '%s'.\n", name);
     157        if (fnode != NULL)
     158                ddf_fun_destroy(fnode);
     159       
     160        printf(NAME ": failed to add function '%s'.\n", name);
    162161       
    163162        return false;
    164163}
    165164
    166 static bool rootpc_add_children(device_t *dev)
    167 {
    168         return rootpc_add_child(dev, "pci0", "intel_pci", &pci_data);
     165static bool rootpc_add_functions(ddf_dev_t *dev)
     166{
     167        return rootpc_add_fun(dev, "pci0", "intel_pci", &pci_data);
    169168}
    170169
     
    175174 * @return              Zero on success, negative error number otherwise.
    176175 */
    177 static int rootpc_add_device(device_t *dev)
     176static int rootpc_add_device(ddf_dev_t *dev)
    178177{
    179178        printf(NAME ": rootpc_add_device, device handle = %d\n",
    180179            (int)dev->handle);
    181180       
    182         /* Register child devices. */
    183         if (!rootpc_add_children(dev)) {
    184                 printf(NAME ": failed to add child devices for PC platform.\n");
     181        /* Register functions. */
     182        if (!rootpc_add_functions(dev)) {
     183                printf(NAME ": failed to add functions for PC platform.\n");
    185184        }
    186185       
     
    190189static void root_pc_init(void)
    191190{
    192         rootpc_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_hw_res_ops;
     191        rootpc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
    193192}
    194193
     
    197196        printf(NAME ": HelenOS PC platform driver\n");
    198197        root_pc_init();
    199         return driver_main(&rootpc_driver);
     198        return ddf_driver_main(&rootpc_driver);
    200199}
    201200
  • uspace/drv/rootvirt/devices.def

    r4837092 r92574f4  
    2222},
    2323#endif
     24#ifdef CONFIG_RUN_VIRTUAL_USB_HC
    2425/* Virtual USB host controller. */
    2526{
     
    2728        .match_id = "usb&hc=vhc"
    2829},
     30#endif
  • uspace/drv/rootvirt/rootvirt.c

    r4837092 r92574f4  
    3939#include <errno.h>
    4040#include <str_error.h>
    41 #include <driver.h>
     41#include <ddf/driver.h>
    4242
    4343#define NAME "rootvirt"
    4444
    45 /** Virtual device entry. */
     45/** Virtual function entry */
    4646typedef struct {
    47         /** Device name. */
     47        /** Function name */
    4848        const char *name;
    49         /** Device match id. */
     49        /** Function match ID */
    5050        const char *match_id;
    51 } virtual_device_t;
     51} virtual_function_t;
    5252
    53 /** List of existing virtual devices. */
    54 virtual_device_t virtual_devices[] = {
     53/** List of existing virtual functions */
     54virtual_function_t virtual_functions[] = {
    5555#include "devices.def"
    56         /* Terminating item. */
     56        /* Terminating item */
    5757        {
    5858                .name = NULL,
     
    6161};
    6262
    63 static int add_device(device_t *dev);
     63static int rootvirt_add_device(ddf_dev_t *dev);
    6464
    6565static driver_ops_t rootvirt_ops = {
    66         .add_device = &add_device
     66        .add_device = &rootvirt_add_device
    6767};
    6868
     
    7272};
    7373
    74 /** Add child device.
     74/** Add function to the virtual device.
    7575 *
    76  * @param parent Parent device.
    77  * @param virt_dev Virtual device to add.
    78  * @return Error code.
     76 * @param vdev          The virtual device
     77 * @param vfun          Virtual function description
     78 * @return              EOK on success or negative error code.
    7979 */
    80 static int add_child(device_t *parent, virtual_device_t *virt_dev)
     80static int rootvirt_add_fun(ddf_dev_t *vdev, virtual_function_t *vfun)
    8181{
    82         printf(NAME ": registering child device `%s' (match \"%s\")\n",
    83             virt_dev->name, virt_dev->match_id);
     82        ddf_fun_t *fun;
     83        int rc;
    8484
    85         int rc = child_device_register_wrapper(parent, virt_dev->name,
    86             virt_dev->match_id, 10, NULL);
     85        printf(NAME ": registering function `%s' (match \"%s\")\n",
     86            vfun->name, vfun->match_id);
    8787
    88         if (rc == EOK) {
    89                 printf(NAME ": registered child device `%s'\n",
    90                     virt_dev->name);
    91         } else {
    92                 printf(NAME ": failed to register child device `%s': %s\n",
    93                     virt_dev->name, str_error(rc));
     88        fun = ddf_fun_create(vdev, fun_inner, vfun->name);
     89        if (fun == NULL) {
     90                printf(NAME ": error creating function %s\n", vfun->name);
     91                return ENOMEM;
    9492        }
    9593
    96         return rc;
     94        rc = ddf_fun_add_match_id(fun, vfun->match_id, 10);
     95        if (rc != EOK) {
     96                printf(NAME ": error adding match IDs to function %s\n",
     97                    vfun->name);
     98                ddf_fun_destroy(fun);
     99                return rc;
     100        }
     101
     102        rc = ddf_fun_bind(fun);
     103        if (rc != EOK) {
     104                printf(NAME ": error binding function %s: %s\n", vfun->name,
     105                    str_error(rc));
     106                ddf_fun_destroy(fun);
     107                return rc;
     108        }
     109
     110        printf(NAME ": registered child device `%s'\n", vfun->name);
     111        return EOK;
    97112}
    98113
    99 static int add_device(device_t *dev)
     114static int rootvirt_add_device(ddf_dev_t *dev)
    100115{
    101116        static int instances = 0;
     
    109124        }
    110125
    111         printf(NAME ": add_device(name=\"%s\", handle=%d)\n",
    112             dev->name, (int)dev->handle);
    113        
     126        printf(NAME ": add_device(handle=%d)\n", (int)dev->handle);
     127
    114128        /*
    115          * Go through all virtual devices and try to add them.
     129         * Go through all virtual functions and try to add them.
    116130         * We silently ignore failures.
    117131         */
    118         virtual_device_t *virt_dev = virtual_devices;
    119         while (virt_dev->name != NULL) {
    120                 (void) add_child(dev, virt_dev);
    121                 virt_dev++;
     132        virtual_function_t *vfun = virtual_functions;
     133        while (vfun->name != NULL) {
     134                (void) rootvirt_add_fun(dev, vfun);
     135                vfun++;
    122136        }
    123137
     
    128142{
    129143        printf(NAME ": HelenOS virtual devices root driver\n");
    130         return driver_main(&rootvirt_driver);
     144        return ddf_driver_main(&rootvirt_driver);
    131145}
    132146
  • uspace/drv/test1/char.c

    r4837092 r92574f4  
    3737#include "test1.h"
    3838
    39 static int impl_char_read(device_t *dev, char *buf, size_t count) {
     39static int impl_char_read(ddf_fun_t *fun, char *buf, size_t count) {
    4040        memset(buf, 0, count);
    4141        return count;
    4242}
    4343
    44 static int imp_char_write(device_t *dev, char *buf, size_t count) {
     44static int imp_char_write(ddf_fun_t *fun, char *buf, size_t count) {
    4545        return count;
    4646}
     
    5151};
    5252
    53 device_ops_t char_device_ops = {
     53ddf_dev_ops_t char_device_ops = {
    5454        .interfaces[CHAR_DEV_IFACE] = &char_dev_ops
    5555};
  • uspace/drv/test1/test1.c

    r4837092 r92574f4  
    3434#include <errno.h>
    3535#include <str_error.h>
     36#include <ddf/driver.h>
     37
    3638#include "test1.h"
    3739
    38 static int add_device(device_t *dev);
     40static int test1_add_device(ddf_dev_t *dev);
    3941
    4042static driver_ops_t driver_ops = {
    41         .add_device = &add_device
     43        .add_device = &test1_add_device
    4244};
    4345
    44 static driver_t the_driver = {
     46static driver_t test1_driver = {
    4547        .name = NAME,
    4648        .driver_ops = &driver_ops
     
    5557 * @param score Device match score.
    5658 */
    57 static void register_child_verbose(device_t *parent, const char *message,
     59static int register_fun_verbose(ddf_dev_t *parent, const char *message,
    5860    const char *name, const char *match_id, int match_score)
    5961{
    60         printf(NAME ": registering child device `%s': %s.\n",
    61            name, message);
     62        ddf_fun_t *fun;
     63        int rc;
    6264
    63         int rc = child_device_register_wrapper(parent, name,
    64             match_id, match_score, NULL);
     65        printf(NAME ": registering function `%s': %s.\n", name, message);
    6566
    66         if (rc == EOK) {
    67                 printf(NAME ": registered child device `%s'.\n", name);
    68         } else {
    69                 printf(NAME ": failed to register child `%s' (%s).\n",
    70                     name, str_error(rc));
     67        fun = ddf_fun_create(parent, fun_inner, name);
     68        if (fun == NULL) {
     69                printf(NAME ": error creating function %s\n", name);
     70                return ENOMEM;
    7171        }
     72
     73        rc = ddf_fun_add_match_id(fun, match_id, match_score);
     74        if (rc != EOK) {
     75                printf(NAME ": error adding match IDs to function %s\n", name);
     76                ddf_fun_destroy(fun);
     77                return rc;
     78        }
     79
     80        rc = ddf_fun_bind(fun);
     81        if (rc != EOK) {
     82                printf(NAME ": error binding function %s: %s\n", name,
     83                    str_error(rc));
     84                ddf_fun_destroy(fun);
     85                return rc;
     86        }
     87
     88        printf(NAME ": registered child device `%s'\n", name);
     89        return EOK;
    7290}
    7391
     
    89107 * @return Error code reporting success of the operation.
    90108 */
    91 static int add_device(device_t *dev)
     109static int test1_add_device(ddf_dev_t *dev)
    92110{
     111        ddf_fun_t *fun_a;
     112        int rc;
     113
    93114        printf(NAME ": add_device(name=\"%s\", handle=%d)\n",
    94115            dev->name, (int) dev->handle);
    95116
    96         add_device_to_class(dev, "virtual");
     117        fun_a = ddf_fun_create(dev, fun_exposed, "a");
     118        if (fun_a == NULL) {
     119                printf(NAME ": error creating function 'a'.\n");
     120                return ENOMEM;
     121        }
     122
     123        rc = ddf_fun_bind(fun_a);
     124        if (rc != EOK) {
     125                printf(NAME ": error binding function 'a'.\n");
     126                return rc;
     127        }
     128
     129        ddf_fun_add_to_class(fun_a, "virtual");
    97130
    98131        if (str_cmp(dev->name, "null") == 0) {
    99                 dev->ops = &char_device_ops;
    100                 add_device_to_class(dev, "virt-null");
    101         } else if (dev->parent == NULL) {
    102                 register_child_verbose(dev, "cloning myself ;-)", "clone",
     132                fun_a->ops = &char_device_ops;
     133                ddf_fun_add_to_class(fun_a, "virt-null");
     134        } else if (str_cmp(dev->name, "test1") == 0) {
     135                (void) register_fun_verbose(dev, "cloning myself ;-)", "clone",
    103136                    "virtual&test1", 10);
    104137        } else if (str_cmp(dev->name, "clone") == 0) {
    105                 register_child_verbose(dev, "run by the same task", "child",
     138                (void) register_fun_verbose(dev, "run by the same task", "child",
    106139                    "virtual&test1&child", 10);
    107140        }
     
    115148{
    116149        printf(NAME ": HelenOS test1 virtual device driver\n");
    117         return driver_main(&the_driver);
     150        return ddf_driver_main(&test1_driver);
    118151}
    119152
  • uspace/drv/test1/test1.h

    r4837092 r92574f4  
    3232#define DRV_TEST1_TEST1_H_
    3333
    34 #include <driver.h>
     34#include <ddf/driver.h>
    3535
    3636#define NAME "test1"
    3737
    38 extern device_ops_t char_device_ops;
     38extern ddf_dev_ops_t char_device_ops;
    3939
    4040#endif
  • uspace/drv/test2/test2.c

    r4837092 r92574f4  
    3131
    3232#include <assert.h>
     33#include <async.h>
    3334#include <stdio.h>
    3435#include <errno.h>
    3536#include <str_error.h>
    36 #include <driver.h>
     37#include <ddf/driver.h>
    3738
    3839#define NAME "test2"
    3940
    40 static int add_device(device_t *dev);
     41static int test2_add_device(ddf_dev_t *dev);
    4142
    4243static driver_ops_t driver_ops = {
    43         .add_device = &add_device
     44        .add_device = &test2_add_device
    4445};
    4546
    46 static driver_t the_driver = {
     47static driver_t test2_driver = {
    4748        .name = NAME,
    4849        .driver_ops = &driver_ops
     
    5758 * @param score Device match score.
    5859 */
    59 static void register_child_verbose(device_t *parent, const char *message,
     60static int register_fun_verbose(ddf_dev_t *parent, const char *message,
    6061    const char *name, const char *match_id, int match_score)
    6162{
    62         printf(NAME ": registering child device `%s': %s.\n",
    63            name, message);
     63        ddf_fun_t *fun;
     64        int rc;
    6465
    65         int rc = child_device_register_wrapper(parent, name,
    66             match_id, match_score, NULL);
     66        printf(NAME ": registering function `%s': %s.\n", name, message);
    6767
    68         if (rc == EOK) {
    69                 printf(NAME ": registered child device `%s'.\n", name);
    70         } else {
    71                 printf(NAME ": failed to register child `%s' (%s).\n",
    72                     name, str_error(rc));
     68        fun = ddf_fun_create(parent, fun_inner, name);
     69        if (fun == NULL) {
     70                printf(NAME ": error creating function %s\n", name);
     71                return ENOMEM;
    7372        }
     73
     74        rc = ddf_fun_add_match_id(fun, match_id, match_score);
     75        if (rc != EOK) {
     76                printf(NAME ": error adding match IDs to function %s\n", name);
     77                ddf_fun_destroy(fun);
     78                return rc;
     79        }
     80
     81        rc = ddf_fun_bind(fun);
     82        if (rc != EOK) {
     83                printf(NAME ": error binding function %s: %s\n", name,
     84                    str_error(rc));
     85                ddf_fun_destroy(fun);
     86                return rc;
     87        }
     88
     89        printf(NAME ": registered child device `%s'\n", name);
     90        return EOK;
    7491}
    7592
    7693/** Add child devices after some sleep.
    7794 *
    78  * @param arg Parent device structure (device_t *).
     95 * @param arg Parent device structure (ddf_dev_t *).
    7996 * @return Always EOK.
    8097 */
    8198static int postponed_birth(void *arg)
    8299{
    83         device_t *dev = (device_t *) arg;
     100        ddf_dev_t *dev = (ddf_dev_t *) arg;
     101        ddf_fun_t *fun_a;
     102        int rc;
    84103
    85104        async_usleep(1000);
    86105
    87         register_child_verbose(dev, "child driven by the same task",
     106        (void) register_fun_verbose(dev, "child driven by the same task",
    88107            "child", "virtual&test2", 10);
    89         register_child_verbose(dev, "child driven by test1",
     108        (void) register_fun_verbose(dev, "child driven by test1",
    90109            "test1", "virtual&test1", 10);
    91110
    92         add_device_to_class(dev, "virtual");
     111        fun_a = ddf_fun_create(dev, fun_exposed, "a");
     112        if (fun_a == NULL) {
     113                printf(NAME ": error creating function 'a'.\n");
     114                return ENOMEM;
     115        }
     116
     117        rc = ddf_fun_bind(fun_a);
     118        if (rc != EOK) {
     119                printf(NAME ": error binding function 'a'.\n");
     120                return rc;
     121        }
     122
     123        ddf_fun_add_to_class(fun_a, "virtual");
    93124
    94125        return EOK;
    95126}
    96127
    97 
    98 static int add_device(device_t *dev)
     128static int test2_add_device(ddf_dev_t *dev)
    99129{
    100         printf(NAME ": add_device(name=\"%s\", handle=%d)\n",
     130        printf(NAME ": test2_add_device(name=\"%s\", handle=%d)\n",
    101131            dev->name, (int) dev->handle);
    102132
    103         if (dev->parent == NULL) {
     133        if (str_cmp(dev->name, "child") != 0) {
    104134                fid_t postpone = fibril_create(postponed_birth, dev);
     135                if (postpone == 0) {
     136                        printf(NAME ": fibril_create() error\n");
     137                        return ENOMEM;
     138                }
    105139                fibril_add_ready(postpone);
    106140        } else {
    107                 register_child_verbose(dev, "child without available driver",
     141                (void) register_fun_verbose(dev, "child without available driver",
    108142                    "ERROR", "non-existent.match.id", 10);
    109143        }
     
    115149{
    116150        printf(NAME ": HelenOS test2 virtual device driver\n");
    117         return driver_main(&the_driver);
     151        return ddf_driver_main(&test2_driver);
    118152}
    119153
  • uspace/drv/uhci-hcd/pci.c

    r4837092 r92574f4  
    3434 * PCI related functions needed by the UHCI driver.
    3535 */
    36 #include "uhci.h"
    3736#include <errno.h>
    3837#include <assert.h>
    3938#include <devman.h>
    4039#include <device/hw_res.h>
     40
     41#include "pci.h"
    4142
    4243/** Get address of registers and IRQ for given device.
     
    4849 * @return Error code.
    4950 */
    50 int pci_get_my_registers(device_t *dev,
     51int pci_get_my_registers(ddf_dev_t *dev,
    5152    uintptr_t *io_reg_address, size_t *io_reg_size,
    5253    int *irq_no)
     
    116117        rc = EOK;
    117118leave:
    118         ipc_hangup(parent_phone);
     119        async_hangup(parent_phone);
    119120
    120121        return rc;
    121122}
     123/*----------------------------------------------------------------------------*/
     124int pci_enable_interrupts(ddf_dev_t *device)
     125{
     126        int parent_phone = devman_parent_device_connect(device->handle,
     127            IPC_FLAG_BLOCKING);
     128        bool enabled = hw_res_enable_interrupt(parent_phone);
     129        return enabled ? EOK : EIO;
     130}
     131/**
     132 * @}
     133 */
    122134
    123135/**
    124136 * @}
    125137 */
    126 
  • uspace/drv/uhci-hcd/pci.h

    r4837092 r92574f4  
    3333 * @brief UHCI driver
    3434 */
    35 #ifndef DRV_UHCI_UHCI_H
    36 #define DRV_UHCI_UHCI_H
     35#ifndef DRV_UHCI_PCI_H
     36#define DRV_UHCI_PCI_H
    3737
    38 #include <usbhc_iface.h>
     38#include <ddf/driver.h>
    3939
    40 #define NAME "uhci"
    41 
    42 usbhc_iface_t uhci_iface;
    43 
    44 int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *);
     40int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
     41int pci_enable_interrupts(ddf_dev_t *);
    4542
    4643#endif
     
    4845 * @}
    4946 */
     47
  • uspace/drv/uhci-hcd/uhci-hcd.ma

    r4837092 r92574f4  
    1110 pci/ven=8086&dev=7020
    2 
     210 pci/ven=8086&dev=7112
  • uspace/drv/usbhid/descdump.c

    r4837092 r92574f4  
    3535
    3636#include <usb/classes/hid.h>
     37#include <stdio.h>
     38#include <assert.h>
    3739
    3840#include "descdump.h"
  • uspace/drv/usbhid/descparser.c

    r4837092 r92574f4  
    3636#include <errno.h>
    3737#include <stdint.h>
     38#include <stdio.h>
    3839#include <usb/usb.h>
    3940#include <usb/classes/hid.h>
  • uspace/drv/usbhid/hid.h

    r4837092 r92574f4  
    4040
    4141#include <usb/classes/hid.h>
    42 #include <driver.h>
     42#include <ddf/driver.h>
    4343#include <usb/pipes.h>
    4444
     
    6969 */
    7070typedef struct {
    71         device_t *device;
     71        ddf_dev_t *device;
    7272        usb_hid_configuration_t *conf;
    73         usb_address_t address;
    7473        usb_hid_report_parser_t *parser;
    7574
    7675        usb_device_connection_t wire;
     76        usb_endpoint_pipe_t ctrl_pipe;
    7777        usb_endpoint_pipe_t poll_pipe;
    7878       
  • uspace/drv/usbhid/main.c

    r4837092 r92574f4  
    3636 */
    3737
    38 #include <usb/usbdrv.h>
    39 #include <driver.h>
     38#include <ddf/driver.h>
    4039#include <ipc/driver.h>
    4140#include <ipc/kbd.h>
     
    4544#include <str_error.h>
    4645#include <fibril.h>
     46#include <usb/debug.h>
     47#include <usb/classes/classes.h>
    4748#include <usb/classes/hid.h>
    4849#include <usb/classes/hidparser.h>
    49 #include <usb/devreq.h>
     50#include <usb/request.h>
    5051#include <usb/descriptor.h>
    51 #include <usb/debug.h>
    5252#include <io/console.h>
    5353#include <stdint.h>
     
    5858#include "layout.h"
    5959
    60 #define BUFFER_SIZE 32
     60#define BUFFER_SIZE 8
    6161#define NAME "usbhid"
    6262
     
    6464#define BOOTP_REPORT_SIZE 6
    6565
    66 static void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *);
    67 static device_ops_t keyboard_ops = {
     66/** Keyboard polling endpoint description for boot protocol class. */
     67static usb_endpoint_description_t poll_endpoint_description = {
     68        .transfer_type = USB_TRANSFER_INTERRUPT,
     69        .direction = USB_DIRECTION_IN,
     70        .interface_class = USB_CLASS_HID,
     71        .interface_subclass = USB_HID_SUBCLASS_BOOT,
     72        .interface_protocol = USB_HID_PROTOCOL_KEYBOARD,
     73        .flags = 0
     74};
     75
     76static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     77static ddf_dev_ops_t keyboard_ops = {
    6878        .default_handler = default_connection_handler
    6979};
     
    7787 * @param icall Call data.
    7888 */
    79 void default_connection_handler(device_t *dev,
     89void default_connection_handler(ddf_fun_t *fun,
    8090    ipc_callid_t icallid, ipc_call_t *icall)
    8191{
     
    8696
    8797                if (console_callback_phone != -1) {
    88                         ipc_answer_0(icallid, ELIMIT);
     98                        async_answer_0(icallid, ELIMIT);
    8999                        return;
    90100                }
    91101
    92102                console_callback_phone = callback;
    93                 ipc_answer_0(icallid, EOK);
     103                async_answer_0(icallid, EOK);
    94104                return;
    95105        }
    96106
    97         ipc_answer_0(icallid, EINVAL);
     107        async_answer_0(icallid, EINVAL);
    98108}
    99109
     
    387397               
    388398                // get the descriptor from the device
    389                 int rc = usb_drv_req_get_descriptor(
    390                     kbd_dev->device->parent_phone, kbd_dev->address,
    391                     USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
    392                     0, i, kbd_dev->conf->interfaces[i].report_desc, length,
     399                int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
     400                    USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
     401                    i, 0,
     402                    kbd_dev->conf->interfaces[i].report_desc, length,
    393403                    &actual_size);
    394404
     
    411421        usb_standard_configuration_descriptor_t config_desc;
    412422       
    413         int rc = usb_drv_req_get_bare_configuration_descriptor(
    414             kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
     423        int rc;
     424        rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe,
     425            0, &config_desc);
    415426       
    416427        if (rc != EOK) {
     
    426437        size_t transferred = 0;
    427438        // get full configuration descriptor
    428         rc = usb_drv_req_get_full_configuration_descriptor(
    429             kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
     439        rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,
     440            0, descriptors,
    430441            config_desc.total_length, &transferred);
    431442       
     
    437448        }
    438449       
     450        /*
     451         * Initialize the interrupt in endpoint.
     452         */
     453        usb_endpoint_mapping_t endpoint_mapping[1] = {
     454                {
     455                        .pipe = &kbd_dev->poll_pipe,
     456                        .description = &poll_endpoint_description,
     457                        .interface_no =
     458                            usb_device_get_assigned_interface(kbd_dev->device)
     459                }
     460        };
     461        rc = usb_endpoint_pipe_initialize_from_configuration(
     462            endpoint_mapping, 1,
     463            descriptors, config_desc.total_length,
     464            &kbd_dev->wire);
     465        if (rc != EOK) {
     466                usb_log_error("Failed to initialize poll pipe: %s.\n",
     467                    str_error(rc));
     468                return rc;
     469        }
     470        if (!endpoint_mapping[0].present) {
     471                usb_log_warning("Not accepting device, " \
     472                    "not boot-protocol keyboard.\n");
     473                return EREFUSED;
     474        }
     475
     476
     477
     478
    439479        kbd_dev->conf = (usb_hid_configuration_t *)calloc(1,
    440480            sizeof(usb_hid_configuration_t));
     
    444484        }
    445485       
    446         rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);
     486        /*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);
    447487        free(descriptors);
    448488        if (rc != EOK) {
     
    451491        }
    452492
    453         // get and report descriptors
     493        // get and report descriptors*/
    454494        rc = usbkbd_get_report_descriptor(kbd_dev);
    455495        if (rc != EOK) {
     
    469509         *    as the endpoint for polling
    470510         */
    471        
     511
    472512        return EOK;
    473513}
    474514
    475 static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
    476 {
     515static usb_hid_dev_kbd_t *usbkbd_init_device(ddf_dev_t *dev)
     516{
     517        int rc;
     518
    477519        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1,
    478520            sizeof(usb_hid_dev_kbd_t));
     
    485527        kbd_dev->device = dev;
    486528
    487         // get phone to my HC and save it as my parent's phone
    488         // TODO: maybe not a good idea if DDF will use parent_phone
    489         int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0);
    490         if (rc < 0) {
    491                 usb_log_error("Problem setting phone to HC.\n");
     529        /*
     530         * Initialize the backing connection to the host controller.
     531         */
     532        rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev);
     533        if (rc != EOK) {
     534                printf("Problem initializing connection to device: %s.\n",
     535                    str_error(rc));
    492536                goto error_leave;
    493537        }
    494538
    495         rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev);
    496         if (rc < 0) {
    497                 usb_log_error("Problem getting address of the device.\n");
     539        /*
     540         * Initialize device pipes.
     541         */
     542        rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe,
     543            &kbd_dev->wire);
     544        if (rc != EOK) {
     545                printf("Failed to initialize default control pipe: %s.\n",
     546                    str_error(rc));
    498547                goto error_leave;
    499548        }
    500549
    501         // doesn't matter now that we have no address
    502 //      if (kbd_dev->address < 0) {
    503 //              usb_log_error("No device address!\n");
    504 //              free(kbd_dev);
    505 //              return NULL;
    506 //      }
    507 
    508550        /*
    509551         * will need all descriptors:
    510          * 1) choose one configuration from configuration descriptors 
     552         * 1) choose one configuration from configuration descriptors
    511553         *    (set it to the device)
    512554         * 2) set endpoints from endpoint descriptors
    513555         */
    514556
    515         usbkbd_process_descriptors(kbd_dev);
    516        
    517         // save the size of the report
    518         kbd_dev->keycode_count = BOOTP_REPORT_SIZE;
    519         kbd_dev->keycodes = (uint8_t *)calloc(
    520             kbd_dev->keycode_count, sizeof(uint8_t));
    521        
    522         if (kbd_dev->keycodes == NULL) {
    523                 usb_log_fatal("No memory!\n");
     557        // TODO: get descriptors, parse descriptors and save endpoints
     558        usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
     559        //usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1);
     560        rc = usbkbd_process_descriptors(kbd_dev);
     561        usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
     562        if (rc != EOK) {
    524563                goto error_leave;
    525564        }
    526        
    527         // set configuration to the first one
    528         // TODO: handle case with no configurations
    529         usb_drv_req_set_configuration(kbd_dev->device->parent_phone,
    530             kbd_dev->address,
    531             kbd_dev->conf->config_descriptor.configuration_number);
    532        
    533         /*
    534          * Initialize the backing connection to the host controller.
    535          */
    536         rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev);
    537         if (rc != EOK) {
    538                 usb_log_error("Problem initializing connection to device: %s."
    539                     "\n", str_error(rc));
    540                 goto error_leave;
    541         }
    542 
    543         /*
    544          * Initialize device pipes.
    545          */
    546         rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire,
    547             GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, USB_DIRECTION_IN);
    548         if (rc != EOK) {
    549                 usb_log_error("Failed to initialize interrupt in pipe: %s.\n",
    550                     str_error(rc));
    551                 goto error_leave;
    552         }
    553 
    554565
    555566        return kbd_dev;
     
    591602
    592603        while (true) {
    593                 async_usleep(1000 * 1000 * 2);
     604                async_usleep(1000 * 10);
    594605
    595606                sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
     
    643654        }
    644655
    645         device_t *dev = (device_t *)arg;
     656        ddf_dev_t *dev = (ddf_dev_t *)arg;
    646657
    647658        // initialize device (get and process descriptors, get address, etc.)
     
    657668}
    658669
    659 static int usbkbd_add_device(device_t *dev)
     670static int usbkbd_add_device(ddf_dev_t *dev)
    660671{
    661672        /* For now, fail immediately. */
     
    679690
    680691        /*
     692         * Create default function.
     693         */
     694        // FIXME - check for errors
     695        ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard");
     696        assert(kbd_fun != NULL);
     697        kbd_fun->ops = &keyboard_ops;
     698
     699        int rc = ddf_fun_bind(kbd_fun);
     700        assert(rc == EOK);
     701        rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
     702        assert(rc == EOK);
     703
     704        /*
    681705         * Create new fibril for handling this keyboard
    682706         */
     
    688712        fibril_add_ready(fid);
    689713
    690         dev->ops = &keyboard_ops;
    691 
    692         add_device_to_class(dev, "keyboard");
     714        //dev->ops = &keyboard_ops;
     715        (void)keyboard_ops;
     716
     717        //add_device_to_class(dev, "keyboard");
    693718
    694719        /*
     
    710735{
    711736        usb_log_enable(USB_LOG_LEVEL_MAX, NAME);
    712         return driver_main(&kbd_driver);
     737        return ddf_driver_main(&kbd_driver);
    713738}
    714739
  • uspace/drv/usbhub/main.c

    r4837092 r92574f4  
    3131 */
    3232
    33 #include <driver.h>
     33#include <ddf/driver.h>
    3434#include <errno.h>
    3535#include <async.h>
    36 
    37 #include <usb/usbdrv.h>
    3836
    3937#include "usbhub.h"
     
    6462int main(int argc, char *argv[])
    6563{
    66         usb_dprintf_enable(NAME, 0);
     64        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    6765       
    6866        fibril_mutex_initialize(&usb_hub_list_lock);
     
    7977        fibril_add_ready(fid);
    8078
    81         return driver_main(&hub_driver);
     79        return ddf_driver_main(&hub_driver);
    8280}
    8381
  • uspace/drv/usbhub/port_status.h

    r4837092 r92574f4  
    3535#include <bool.h>
    3636#include <sys/types.h>
    37 #include <usb/devreq.h>
     37#include <usb/request.h>
    3838#include "usbhub_private.h"
    3939
  • uspace/drv/usbhub/usbhub.c

    r4837092 r92574f4  
    3333 */
    3434
    35 #include <driver.h>
     35#include <ddf/driver.h>
    3636#include <bool.h>
    3737#include <errno.h>
     38#include <str_error.h>
    3839
    3940#include <usb_iface.h>
    40 #include <usb/usbdrv.h>
     41#include <usb/ddfiface.h>
    4142#include <usb/descriptor.h>
    42 #include <usb/devreq.h>
     43#include <usb/recognise.h>
     44#include <usb/request.h>
    4345#include <usb/classes/hub.h>
    4446
     
    4749#include "port_status.h"
    4850#include "usb/usb.h"
    49 
    50 static usb_iface_t hub_usb_iface = {
    51         .get_hc_handle = usb_drv_find_hc
     51#include "usb/pipes.h"
     52#include "usb/classes/classes.h"
     53
     54static ddf_dev_ops_t hub_device_ops = {
     55        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
    5256};
    5357
    54 static device_ops_t hub_device_ops = {
    55         .interfaces[USB_DEV_IFACE] = &hub_usb_iface
     58/** Hub status-change endpoint description */
     59static usb_endpoint_description_t status_change_endpoint_description = {
     60        .transfer_type = USB_TRANSFER_INTERRUPT,
     61        .direction = USB_DIRECTION_IN,
     62        .interface_class = USB_CLASS_HUB,
     63        .flags = 0
    5664};
     65
    5766
    5867//*********************************************
     
    6271//*********************************************
    6372
    64 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) {
     73/**
     74 * Initialize connnections to host controller, device, and device
     75 * control endpoint
     76 * @param hub
     77 * @param device
     78 * @return
     79 */
     80static int usb_hub_init_communication(usb_hub_info_t * hub){
     81        usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle);
     82        int opResult;
     83        opResult = usb_device_connection_initialize_from_device(
     84                        &hub->device_connection,
     85                        hub->device);
     86        if(opResult != EOK){
     87                dprintf(USB_LOG_LEVEL_ERROR,
     88                                "could not initialize connection to hc, errno %d",opResult);
     89                return opResult;
     90        }
     91        usb_log_debug("Initializing USB wire abstraction.\n");
     92        opResult = usb_hc_connection_initialize_from_device(&hub->connection,
     93                        hub->device);
     94        if(opResult != EOK){
     95                dprintf(USB_LOG_LEVEL_ERROR,
     96                                "could not initialize connection to device, errno %d",opResult);
     97                return opResult;
     98        }
     99        usb_log_debug("Initializing default control pipe.\n");
     100        opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
     101            &hub->device_connection);
     102        if(opResult != EOK){
     103                dprintf(USB_LOG_LEVEL_ERROR,
     104                                "could not initialize connection to device endpoint, errno %d",opResult);
     105        }
     106        return opResult;
     107}
     108
     109/**
     110 * When entering this function, hub->endpoints.control should be active.
     111 * @param hub
     112 * @return
     113 */
     114static int usb_hub_process_configuration_descriptors(
     115        usb_hub_info_t * hub){
     116        if(hub==NULL) {
     117                return EINVAL;
     118        }
     119        int opResult;
     120       
     121        //device descriptor
     122        usb_standard_device_descriptor_t std_descriptor;
     123        opResult = usb_request_get_device_descriptor(&hub->endpoints.control,
     124            &std_descriptor);
     125        if(opResult!=EOK){
     126                dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult);
     127                return opResult;
     128        }
     129        dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations",
     130                        std_descriptor.configuration_count);
     131        if(std_descriptor.configuration_count<1){
     132                dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE");
     133                //shouldn`t I return?
     134        }
     135
     136        //configuration descriptor
     137        /// \TODO check other configurations
     138        usb_standard_configuration_descriptor_t config_descriptor;
     139        opResult = usb_request_get_bare_configuration_descriptor(
     140            &hub->endpoints.control, 0,
     141        &config_descriptor);
     142        if(opResult!=EOK){
     143                dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
     144                return opResult;
     145        }
     146        //set configuration
     147        opResult = usb_request_set_configuration(&hub->endpoints.control,
     148                config_descriptor.configuration_number);
     149
     150        if (opResult != EOK) {
     151                dprintf(USB_LOG_LEVEL_ERROR,
     152                                "something went wrong when setting hub`s configuration, %d",
     153                                opResult);
     154                return opResult;
     155        }
     156        dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",
     157                        config_descriptor.configuration_number);
     158
     159        //full configuration descriptor
     160        size_t transferred = 0;
     161        uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length);
     162        if (descriptors == NULL) {
     163                dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory");
     164                return ENOMEM;
     165        }
     166        opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control,
     167            0, descriptors,
     168            config_descriptor.total_length, &transferred);
     169        if(opResult!=EOK){
     170                free(descriptors);
     171                dprintf(USB_LOG_LEVEL_ERROR,
     172                                "could not get full configuration descriptor, %d",opResult);
     173                return opResult;
     174        }
     175        if (transferred != config_descriptor.total_length) {
     176                dprintf(USB_LOG_LEVEL_ERROR,
     177                                "received incorrect full configuration descriptor");
     178                return ELIMIT;
     179        }
     180
     181        /**
     182         * Initialize the interrupt in endpoint.
     183         * \TODO this code should be checked...
     184         */
     185        usb_endpoint_mapping_t endpoint_mapping[1] = {
     186                {
     187                        .pipe = &hub->endpoints.status_change,
     188                        .description = &status_change_endpoint_description,
     189                        .interface_no =
     190                            usb_device_get_assigned_interface(hub->device)
     191                }
     192        };
     193        opResult = usb_endpoint_pipe_initialize_from_configuration(
     194            endpoint_mapping, 1,
     195            descriptors, config_descriptor.total_length,
     196            &hub->device_connection);
     197        if (opResult != EOK) {
     198                dprintf(USB_LOG_LEVEL_ERROR,
     199                                "Failed to initialize status change pipe: %s",
     200                    str_error(opResult));
     201                return opResult;
     202        }
     203        if (!endpoint_mapping[0].present) {
     204                dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \
     205                    "cannot understand what is happenning");
     206                return EREFUSED;
     207        }
     208
     209        free(descriptors);
     210        return EOK;
     211       
     212
     213        // Initialize the interrupt(=status change) endpoint.
     214        /*usb_endpoint_pipe_initialize(
     215                &result->endpoints->status_change,
     216                &result->device_connection, );USB_TRANSFER_INTERRUPT
     217        USB_DIRECTION_IN*/
     218
     219}
     220
     221
     222/**
     223 * Create hub representation from device information.
     224 * @param device
     225 * @return pointer to created structure or NULL in case of error
     226 */
     227usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
    65228        usb_hub_info_t* result = usb_new(usb_hub_info_t);
     229        result->device = device;
     230        int opResult;
     231        opResult = usb_hub_init_communication(result);
     232        if(opResult != EOK){
     233                free(result);
     234                return NULL;
     235        }
     236
    66237        //result->device = device;
    67238        result->port_count = -1;
    68         /// \TODO is this correct? is the device stored?
    69239        result->device = device;
    70240
    71 
    72         //printf("[usb_hub] phone to hc = %d\n", hc);
    73         if (hc < 0) {
    74                 return result;
    75         }
    76         //get some hub info
    77         usb_address_t addr = usb_drv_get_my_address(hc, device);
    78         dprintf(1, "address of newly created hub = %d", addr);
    79         /*if(addr<0){
    80                 //return result;
    81 
    82         }*/
    83 
    84         result->usb_device = usb_new(usb_hcd_attached_device_info_t);
    85         result->usb_device->address = addr;
     241        //result->usb_device = usb_new(usb_hcd_attached_device_info_t);
     242        size_t received_size;
    86243
    87244        // get hub descriptor
    88 
    89         //printf("[usb_hub] creating serialized descriptor\n");
     245        dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton");
    90246        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    91247        usb_hub_descriptor_t * descriptor;
    92         size_t received_size;
    93         int opResult;
    94         //printf("[usb_hub] starting control transaction\n");
    95        
    96         opResult = usb_drv_req_get_descriptor(hc, addr,
     248        dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction");
     249        usb_endpoint_pipe_start_session(&result->endpoints.control);
     250        opResult = usb_request_get_descriptor(&result->endpoints.control,
    97251                        USB_REQUEST_TYPE_CLASS,
    98252                        USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
    99253                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    100 
    101         if (opResult != EOK) {
    102                 dprintf(1, "failed when receiving hub descriptor, badcode = %d",opResult);
     254        usb_endpoint_pipe_end_session(&result->endpoints.control);
     255
     256        if (opResult != EOK) {
     257                dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult);
    103258                free(serialized_descriptor);
    104259                return result;
    105260        }
    106         //printf("[usb_hub] deserializing descriptor\n");
     261        dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor");
    107262        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    108263        if(descriptor==NULL){
    109                 dprintf(1, "could not deserialize descriptor ");
     264                dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor ");
    110265                result->port_count = 1;///\TODO this code is only for debug!!!
    111266                return result;
    112267        }
    113         //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
     268
     269       
     270        dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
    114271        result->port_count = descriptor->ports_count;
    115         result->attached_devs = (usb_hub_attached_device_t*)
    116             malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t));
     272        result->attached_devs = (usb_hc_attached_device_t*)
     273            malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t));
    117274        int i;
    118275        for(i=0;i<result->port_count+1;++i){
    119                 result->attached_devs[i].devman_handle=0;
     276                result->attached_devs[i].handle=0;
    120277                result->attached_devs[i].address=0;
    121278        }
    122         //printf("[usb_hub] freeing data\n");
     279        dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data");
    123280        free(serialized_descriptor);
    124281        free(descriptor->devices_removable);
     
    127284        //finish
    128285
    129         dprintf(1, "hub info created");
     286        dprintf(USB_LOG_LEVEL_INFO, "hub info created");
    130287
    131288        return result;
    132289}
    133290
    134 int usb_add_hub_device(device_t *dev) {
    135         dprintf(1, "add_hub_device(handle=%d)", (int) dev->handle);
    136         dprintf(1, "hub device");
    137 
    138         /*
    139          * We are some (probably deeply nested) hub.
    140          * Thus, assign our own operations and explore already
    141          * connected devices.
    142          */
    143         dev->ops = &hub_device_ops;
    144 
    145         //create the hub structure
    146         //get hc connection
    147         int hc = usb_drv_hc_connect_auto(dev, 0);
    148         if (hc < 0) {
    149                 return hc;
    150         }
    151 
    152         usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc);
     291/**
     292 * Create hub representation and add it into hub list
     293 * @param dev
     294 * @return
     295 */
     296int usb_add_hub_device(ddf_dev_t *dev) {
     297        dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle);
     298
     299        //dev->ops = &hub_device_ops;
     300        (void) hub_device_ops;
     301
     302        usb_hub_info_t * hub_info = usb_create_hub_info(dev);
     303
     304        int opResult;
     305
     306        //perform final configurations
     307        usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
     308        // process descriptors
     309        opResult = usb_hub_process_configuration_descriptors(hub_info);
     310        if(opResult != EOK){
     311                dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d",
     312                                opResult);
     313                return opResult;
     314        }
     315        //power ports
     316        usb_device_request_setup_packet_t request;
    153317        int port;
    154         int opResult;
    155         usb_target_t target;
    156         target.address = hub_info->usb_device->address;
    157         target.endpoint = 0;
    158 
    159         //get configuration descriptor
    160         // this is not fully correct - there are more configurations
    161         // and all should be checked
    162         usb_standard_device_descriptor_t std_descriptor;
    163         opResult = usb_drv_req_get_device_descriptor(hc, target.address,
    164             &std_descriptor);
    165         if(opResult!=EOK){
    166                 dprintf(1, "could not get device descriptor, %d",opResult);
    167                 return opResult;
    168         }
    169         dprintf(1, "hub has %d configurations",std_descriptor.configuration_count);
    170         if(std_descriptor.configuration_count<1){
    171                 dprintf(1, "THERE ARE NO CONFIGURATIONS AVAILABLE");
    172                 //shouldn`t I return?
    173         }
    174         /// \TODO check other configurations
    175         usb_standard_configuration_descriptor_t config_descriptor;
    176         opResult = usb_drv_req_get_bare_configuration_descriptor(hc,
    177         target.address, 0,
    178         &config_descriptor);
    179         if(opResult!=EOK){
    180                 dprintf(1, "could not get configuration descriptor, %d",opResult);
    181                 return opResult;
    182         }
    183         //set configuration
    184         opResult = usb_drv_req_set_configuration(hc, target.address,
    185     config_descriptor.configuration_number);
    186 
    187         if (opResult != EOK) {
    188                 dprintf(1, "something went wrong when setting hub`s configuration, %d", opResult);
    189         }
    190 
    191         usb_device_request_setup_packet_t request;
    192318        for (port = 1; port < hub_info->port_count+1; ++port) {
    193319                usb_hub_set_power_port_request(&request, port);
    194                 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
    195                 dprintf(1, "powering port %d",port);
     320                opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control,
     321                                &request,sizeof(usb_device_request_setup_packet_t), NULL, 0);
     322                dprintf(USB_LOG_LEVEL_INFO, "powering port %d",port);
    196323                if (opResult != EOK) {
    197                         dprintf(1, "something went wrong when setting hub`s %dth port", port);
     324                        dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port);
    198325                }
    199326        }
    200327        //ports powered, hub seems to be enabled
    201 
    202         ipc_hangup(hc);
     328        usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
    203329
    204330        //add the hub to list
     
    207333        fibril_mutex_unlock(&usb_hub_list_lock);
    208334
    209         dprintf(1, "hub info added to list");
     335        dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list");
    210336        //(void)hub_info;
    211337        usb_hub_check_hub_changes();
    212 
    213338       
    214 
    215         dprintf(1, "hub dev added");
    216         dprintf(1, "\taddress %d, has %d ports ",
    217                         hub_info->usb_device->address,
     339        dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
     340        //address is lost...
     341        dprintf(USB_LOG_LEVEL_DEBUG, "\taddress %d, has %d ports ",
     342                        //hub_info->endpoints.control.,
    218343                        hub_info->port_count);
    219         dprintf(1, "\tused configuration %d",config_descriptor.configuration_number);
    220344
    221345        return EOK;
     
    231355
    232356/**
    233  * Convenience function for releasing default address and writing debug info
    234  * (these few lines are used too often to be written again and again).
    235  * @param hc
    236  * @return
    237  */
    238 inline static int usb_hub_release_default_address(int hc){
    239         int opResult;
    240         dprintf(1, "releasing default address");
    241         opResult = usb_drv_release_default_address(hc);
    242         if (opResult != EOK) {
    243                 dprintf(1, "failed to release default address");
    244         }
    245         return opResult;
    246 }
    247 
    248 /**
    249357 * Reset the port with new device and reserve the default address.
    250358 * @param hc
     
    252360 * @param target
    253361 */
    254 static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
     362static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) {
    255363        usb_device_request_setup_packet_t request;
    256364        int opResult;
    257         dprintf(1, "some connection changed");
     365        dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
     366        assert(hub->endpoints.control.hc_phone);
    258367        //get default address
    259         opResult = usb_drv_reserve_default_address(hc);
    260         if (opResult != EOK) {
    261                 dprintf(1, "cannot assign default address, it is probably used");
     368        //opResult = usb_drv_reserve_default_address(hc);
     369        opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
     370
     371        if (opResult != EOK) {
     372                dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used");
    262373                return;
    263374        }
    264375        //reset port
    265376        usb_hub_set_reset_port_request(&request, port);
    266         opResult = usb_drv_sync_control_write(
    267                         hc, target,
    268                         &request,
     377        opResult = usb_endpoint_pipe_control_write(
     378                        &hub->endpoints.control,
     379                        &request,sizeof(usb_device_request_setup_packet_t),
    269380                        NULL, 0
    270381                        );
    271382        if (opResult != EOK) {
    272                 dprintf(1, "something went wrong when reseting a port");
    273                 usb_hub_release_default_address(hc);
     383                dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port");
     384                //usb_hub_release_default_address(hc);
     385                usb_hc_release_default_address(&hub->connection);
    274386        }
    275387}
     
    282394 */
    283395static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
    284                 int hc, uint16_t port, usb_target_t target) {
     396                uint16_t port) {
    285397
    286398        int opResult;
    287         dprintf(1, "finalizing add device");
    288         opResult = usb_hub_clear_port_feature(hc, target.address,
     399        dprintf(USB_LOG_LEVEL_INFO, "finalizing add device");
     400        opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
    289401            port, USB_HUB_FEATURE_C_PORT_RESET);
    290         if (opResult != EOK) {
    291                 dprintf(1, "failed to clear port reset feature");
    292                 usb_hub_release_default_address(hc);
    293                 return;
    294         }
    295 
    296         /* Request address at from host controller. */
    297         usb_address_t new_device_address = usb_drv_request_address(hc);
     402
     403        if (opResult != EOK) {
     404                dprintf(USB_LOG_LEVEL_ERROR, "failed to clear port reset feature");
     405                usb_hc_release_default_address(&hub->connection);
     406                return;
     407        }
     408        //create connection to device
     409        usb_endpoint_pipe_t new_device_pipe;
     410        usb_device_connection_t new_device_connection;
     411        usb_device_connection_initialize_on_default_address(
     412                        &new_device_connection,
     413                        &hub->connection
     414                        );
     415        usb_endpoint_pipe_initialize_default_control(
     416                        &new_device_pipe,
     417                        &new_device_connection);
     418        /// \TODO get highspeed info
     419
     420
     421
     422
     423
     424        /* Request address from host controller. */
     425        usb_address_t new_device_address = usb_hc_request_address(
     426                        &hub->connection,
     427                        USB_SPEED_LOW/// \TODO fullspeed??
     428                        );
    298429        if (new_device_address < 0) {
    299                 dprintf(1, "failed to get free USB address");
     430                dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address");
    300431                opResult = new_device_address;
    301                 usb_hub_release_default_address(hc);
    302                 return;
    303         }
    304         dprintf(1, "setting new address");
    305         opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    306             new_device_address);
    307 
    308         if (opResult != EOK) {
    309                 dprintf(1, "could not set address for new device");
    310                 usb_hub_release_default_address(hc);
    311                 return;
    312         }
    313 
    314 
    315         opResult = usb_hub_release_default_address(hc);
     432                usb_hc_release_default_address(&hub->connection);
     433                return;
     434        }
     435        dprintf(USB_LOG_LEVEL_INFO, "setting new address %d",new_device_address);
     436        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
     437        //    new_device_address);
     438        opResult = usb_request_set_address(&new_device_pipe,new_device_address);
     439
     440        if (opResult != EOK) {
     441                dprintf(USB_LOG_LEVEL_ERROR, "could not set address for new device");
     442                usb_hc_release_default_address(&hub->connection);
     443                return;
     444        }
     445
     446
     447        //opResult = usb_hub_release_default_address(hc);
     448        opResult = usb_hc_release_default_address(&hub->connection);
    316449        if(opResult!=EOK){
    317450                return;
     
    319452
    320453        devman_handle_t child_handle;
    321         opResult = usb_drv_register_child_in_devman(hc, hub->device,
    322             new_device_address, &child_handle);
    323         if (opResult != EOK) {
    324                 dprintf(1, "could not start driver for new device");
    325                 return;
    326         }
    327         hub->attached_devs[port].devman_handle = child_handle;
     454        //??
     455    opResult = usb_device_register_child_in_devman(new_device_address,
     456            hub->connection.hc_handle, hub->device, &child_handle,
     457            NULL, NULL, NULL);
     458
     459        if (opResult != EOK) {
     460                dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device");
     461                return;
     462        }
     463        hub->attached_devs[port].handle = child_handle;
    328464        hub->attached_devs[port].address = new_device_address;
    329465
    330         opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
    331         if (opResult != EOK) {
    332                 dprintf(1, "could not assign address of device in hcd");
    333                 return;
    334         }
    335         dprintf(1, "new device address %d, handle %zu",
     466        //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
     467        opResult = usb_hc_register_device(
     468                        &hub->connection,
     469                        &hub->attached_devs[port]);
     470        if (opResult != EOK) {
     471                dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd");
     472                return;
     473        }
     474        dprintf(USB_LOG_LEVEL_INFO, "new device address %d, handle %zu",
    336475            new_device_address, child_handle);
    337476
     
    345484 */
    346485static void usb_hub_removed_device(
    347     usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {
     486    usb_hub_info_t * hub,uint16_t port) {
    348487        //usb_device_request_setup_packet_t request;
    349488        int opResult;
     
    352491         * devide manager
    353492         */
    354 
    355         hub->attached_devs[port].devman_handle=0;
     493       
    356494        //close address
    357495        if(hub->attached_devs[port].address!=0){
    358                 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     496                //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     497                opResult = usb_hc_unregister_device(
     498                                &hub->connection, hub->attached_devs[port].address);
    359499                if(opResult != EOK) {
    360                         dprintf(1, "could not release address of " \
     500                        dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
    361501                            "removed device: %d", opResult);
    362502                }
    363503                hub->attached_devs[port].address = 0;
     504                hub->attached_devs[port].handle = 0;
    364505        }else{
    365                 dprintf(1, "this is strange, disconnected device had no address");
     506                dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address");
    366507                //device was disconnected before it`s port was reset - return default address
    367                 usb_drv_release_default_address(hc);
     508                //usb_drv_release_default_address(hc);
     509                usb_hc_release_default_address(&hub->connection);
    368510        }
    369511}
     
    375517 * @param target
    376518 */
    377 static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,
    378         uint16_t port, usb_address_t address) {
    379         dprintf(1, "interrupt at port %d", port);
     519static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     520        uint16_t port) {
     521        dprintf(USB_LOG_LEVEL_DEBUG, "interrupt at port %d", port);
    380522        //determine type of change
     523        usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
     524        int opResult = usb_endpoint_pipe_start_session(pipe);
     525       
     526        if(opResult != EOK){
     527                dprintf(USB_LOG_LEVEL_ERROR, "cannot open pipe %d", opResult);
     528        }
     529
     530        /*
    381531        usb_target_t target;
    382532        target.address=address;
    383533        target.endpoint=0;
     534        */
     535
    384536        usb_port_status_t status;
    385537        size_t rcvd_size;
    386538        usb_device_request_setup_packet_t request;
    387         int opResult;
     539        //int opResult;
    388540        usb_hub_set_port_status_request(&request, port);
    389541        //endpoint 0
    390542
    391         opResult = usb_drv_sync_control_read(
    392                         hc, target,
    393                         &request,
     543        opResult = usb_endpoint_pipe_control_read(
     544                        pipe,
     545                        &request, sizeof(usb_device_request_setup_packet_t),
    394546                        &status, 4, &rcvd_size
    395547                        );
    396548        if (opResult != EOK) {
    397                 dprintf(1, "ERROR: could not get port status");
     549                dprintf(USB_LOG_LEVEL_ERROR, "ERROR: could not get port status");
    398550                return;
    399551        }
    400552        if (rcvd_size != sizeof (usb_port_status_t)) {
    401                 dprintf(1, "ERROR: received status has incorrect size");
     553                dprintf(USB_LOG_LEVEL_ERROR, "ERROR: received status has incorrect size");
    402554                return;
    403555        }
    404556        //something connected/disconnected
    405557        if (usb_port_connect_change(&status)) {
    406                 opResult = usb_hub_clear_port_feature(hc, target.address,
     558                opResult = usb_hub_clear_port_feature(pipe,
    407559                    port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    408560                // TODO: check opResult
    409561                if (usb_port_dev_connected(&status)) {
    410                         dprintf(1, "some connection changed");
    411                         usb_hub_init_add_device(hc, port, target);
     562                        dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
     563                        usb_hub_init_add_device(hub, port);
    412564                } else {
    413                         usb_hub_removed_device(hub, hc, port, target);
     565                        usb_hub_removed_device(hub, port);
    414566                }
    415567        }
    416568        //port reset
    417569        if (usb_port_reset_completed(&status)) {
    418                 dprintf(1, "port reset complete");
     570                dprintf(USB_LOG_LEVEL_INFO, "port reset complete");
    419571                if (usb_port_enabled(&status)) {
    420                         usb_hub_finalize_add_device(hub, hc, port, target);
     572                        usb_hub_finalize_add_device(hub, port);
    421573                } else {
    422                         dprintf(1, "ERROR: port reset, but port still not enabled");
     574                        dprintf(USB_LOG_LEVEL_WARNING, "ERROR: port reset, but port still not enabled");
    423575                }
    424576        }
     
    429581        usb_port_set_dev_connected(&status, false);
    430582        if (status>>16) {
    431                 dprintf(1, "there was some unsupported change on port %d: %X",port,status);
     583                dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status);
    432584
    433585        }
    434586        /// \TODO handle other changes
    435587        /// \TODO debug log for various situations
     588        usb_endpoint_pipe_end_session(pipe);
     589
    436590
    437591}
     
    451605                fibril_mutex_unlock(&usb_hub_list_lock);
    452606                usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
     607                int opResult;
     608
     609                opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
     610                if(opResult != EOK){
     611                        continue;
     612                }
    453613                /*
    454614                 * Check status change pipe of this hub.
    455615                 */
    456 
     616                /*
    457617                usb_target_t target;
    458                 target.address = hub_info->usb_device->address;
     618                target.address = hub_info->address;
    459619                target.endpoint = 1;/// \TODO get from endpoint descriptor
    460                 dprintf(1, "checking changes for hub at addr %d",
     620                dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d",
    461621                    target.address);
    462 
     622                */
    463623                size_t port_count = hub_info->port_count;
    464624
    465625                /*
    466626                 * Connect to respective HC.
    467                  */
     627                 *
    468628                int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
    469629                if (hc < 0) {
    470630                        continue;
    471                 }
     631                }*/
    472632
    473633                /// FIXME: count properly
     
    476636                void *change_bitmap = malloc(byte_length);
    477637                size_t actual_size;
    478                 usb_handle_t handle;
     638                //usb_handle_t handle;
    479639
    480640                /*
    481641                 * Send the request.
    482642                 */
    483                 int opResult = usb_drv_async_interrupt_in(hc, target,
    484                                 change_bitmap, byte_length, &actual_size,
    485                                 &handle);
    486 
    487                 usb_drv_async_wait_for(handle);
     643                opResult = usb_endpoint_pipe_read(
     644                                &hub_info->endpoints.status_change,
     645                                change_bitmap, byte_length, &actual_size
     646                                );
     647
     648                //usb_drv_async_wait_for(handle);
    488649
    489650                if (opResult != EOK) {
    490651                        free(change_bitmap);
    491                         dprintf(1, "something went wrong while getting status of hub");
     652                        dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
    492653                        continue;
    493654                }
     
    498659                        if (interrupt) {
    499660                                usb_hub_process_interrupt(
    500                                         hub_info, hc, port, hub_info->usb_device->address);
     661                                        hub_info, port);
    501662                        }
    502663                }
     664                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
    503665                free(change_bitmap);
    504 
    505                 ipc_hangup(hc);
     666               
     667
     668                //async_hangup(hc);
    506669                fibril_mutex_lock(&usb_hub_list_lock);
    507670        }
  • uspace/drv/usbhub/usbhub.h

    r4837092 r92574f4  
    3636#define DRV_USBHUB_USBHUB_H
    3737
     38#include <ipc/devman.h>
     39#include <usb/usb.h>
     40#include <ddf/driver.h>
     41
    3842#define NAME "usbhub"
    3943
    40 #include "usb/hcdhubd.h"
     44#include <usb/hub.h>
    4145
    42 /** basic information about device attached to hub */
    43 typedef struct{
    44         usb_address_t address;
    45         devman_handle_t devman_handle;
    46 }usb_hub_attached_device_t;
     46#include <usb/pipes.h>
     47
     48/* Hub endpoints. */
     49typedef struct {
     50        usb_endpoint_pipe_t control;
     51        usb_endpoint_pipe_t status_change;
     52} usb_hub_endpoints_t;
     53
     54
    4755
    4856/** Information about attached hub. */
     
    5058        /** Number of ports. */
    5159        int port_count;
    52         /** attached device handles */
    53         usb_hub_attached_device_t * attached_devs;
     60        /** attached device handles, for each port one */
     61        usb_hc_attached_device_t * attached_devs;
    5462        /** General usb device info. */
    55         usb_hcd_attached_device_info_t * usb_device;
     63        //usb_hcd_attached_device_info_t * usb_device;
    5664        /** General device info*/
    57         device_t * device;
    58 
     65        ddf_dev_t * device;
     66        /** connection to hcd */
     67        //usb_device_connection_t connection;
     68        usb_hc_connection_t connection;
     69        /** */
     70        usb_device_connection_t device_connection;
     71        /** hub endpoints */
     72        usb_hub_endpoints_t endpoints;
    5973} usb_hub_info_t;
    6074
     
    7084 * @return Error code.
    7185 */
    72 int usb_add_hub_device(device_t *dev);
     86int usb_add_hub_device(ddf_dev_t *dev);
    7387
    7488/**
  • uspace/drv/usbhub/usbhub_private.h

    r4837092 r92574f4  
    4242#include <adt/list.h>
    4343#include <bool.h>
    44 #include <driver.h>
     44#include <ddf/driver.h>
    4545#include <fibril_synch.h>
    4646
     47#include <usb/classes/hub.h>
    4748#include <usb/usb.h>
    48 #include <usb/usbdrv.h>
    49 #include <usb/classes/hub.h>
    50 #include <usb/devreq.h>
    5149#include <usb/debug.h>
     50#include <usb/request.h>
    5251
    5352//************
     
    6160//************
    6261//
    63 // convenience debug printf
     62// convenience debug printf for usb hub
    6463//
    6564//************
    6665#define dprintf(level, format, ...) \
    67         usb_dprintf(NAME, (level), format "\n", ##__VA_ARGS__)
     66        usb_log_printf((level), format "\n", ##__VA_ARGS__)
     67
    6868
    6969/**
     
    7676 * @return
    7777 */
    78 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc);
     78usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device);
    7979
    8080/** List of hubs maanged by this driver */
     
    9797 * @return error code
    9898 */
     99/*
    99100int usb_drv_sync_control_read(
    100     int phone, usb_target_t target,
     101    usb_endpoint_pipe_t *pipe,
    101102    usb_device_request_setup_packet_t * request,
    102103    void * rcvd_buffer, size_t rcvd_size, size_t * actual_size
    103 );
     104);*/
    104105
    105106/**
     
    114115 * @return error code
    115116 */
    116 int usb_drv_sync_control_write(
    117     int phone, usb_target_t target,
     117/*int usb_drv_sync_control_write(
     118    usb_endpoint_pipe_t *pipe,
    118119    usb_device_request_setup_packet_t * request,
    119120    void * sent_buffer, size_t sent_size
    120 );
     121);*/
    121122
    122123/**
     
    146147 * @return Operation result
    147148 */
    148 static inline int usb_hub_clear_port_feature(int hc, usb_address_t address,
     149static inline int usb_hub_clear_port_feature(usb_endpoint_pipe_t *pipe,
    149150    int port_index,
    150151    usb_hub_class_feature_t feature) {
    151         usb_target_t target = {
    152                 .address = address,
    153                 .endpoint = 0
    154         };
     152       
    155153        usb_device_request_setup_packet_t clear_request = {
    156154                .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
     
    160158        };
    161159        clear_request.value = feature;
    162         return usb_drv_psync_control_write(hc, target, &clear_request,
     160        return usb_endpoint_pipe_control_write(pipe, &clear_request,
    163161            sizeof(clear_request), NULL, 0);
    164162}
  • uspace/drv/usbhub/utils.c

    r4837092 r92574f4  
    3333 * @brief various utilities
    3434 */
    35 #include <driver.h>
     35#include <ddf/driver.h>
    3636#include <bool.h>
    3737#include <errno.h>
    3838
    3939#include <usbhc_iface.h>
    40 #include <usb/usbdrv.h>
    4140#include <usb/descriptor.h>
    42 #include <usb/devreq.h>
    4341#include <usb/classes/hub.h>
    4442
     
    114112
    115113//control transactions
    116 
     114/*
    117115int usb_drv_sync_control_read(
    118                 int phone, usb_target_t target,
    119                 usb_device_request_setup_packet_t * request,
    120                 void * rcvd_buffer, size_t rcvd_size, size_t * actual_size
    121                 ) {
     116    int phone, usb_target_t target,
     117    usb_device_request_setup_packet_t * request,
     118    void * rcvd_buffer, size_t rcvd_size, size_t * actual_size
     119) {
    122120        usb_handle_t handle;
    123121        int opResult;
    124122        //setup
    125123        opResult = usb_drv_async_control_read_setup(phone, target,
    126                         request, sizeof (usb_device_request_setup_packet_t),
    127                         &handle);
     124            request, sizeof (usb_device_request_setup_packet_t),
     125            &handle);
    128126        if (opResult != EOK) {
    129127                return opResult;
     
    158156
    159157int usb_drv_sync_control_write(
    160                 int phone, usb_target_t target,
    161                 usb_device_request_setup_packet_t * request,
    162                 void * sent_buffer, size_t sent_size
    163                 ) {
     158    int phone, usb_target_t target,
     159    usb_device_request_setup_packet_t * request,
     160    void * sent_buffer, size_t sent_size
     161) {
    164162        usb_handle_t handle;
    165163        int opResult;
    166164        //setup
    167165        opResult = usb_drv_async_control_write_setup(phone, target,
    168                         request, sizeof (usb_device_request_setup_packet_t),
    169                         &handle);
     166            request, sizeof (usb_device_request_setup_packet_t),
     167            &handle);
    170168        if (opResult != EOK) {
    171169                return opResult;
     
    188186        //finalize
    189187        opResult = usb_drv_async_control_write_status(phone, target,
    190                         &handle);
     188            &handle);
    191189        if (opResult != EOK) {
    192190                return opResult;
     
    199197}
    200198
    201 
     199*/
    202200
    203201
  • uspace/drv/usbmid/Makefile

    r4837092 r92574f4  
    11#
    2 # Copyright (c) 2010 Vojtech Horky
     2# Copyright (c) 2011 Vojtech Horky
    33# All rights reserved.
    44#
     
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
    32 BINARY = uhci
     32BINARY = usbmid
    3333
    3434SOURCES = \
     35        dump.c \
     36        explore.c \
    3537        main.c \
    36         pci.c \
    37         transfers.c
     38        usbmid.c
    3839
    3940include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/usbmid/main.c

    r4837092 r92574f4  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 #include <usb/hcdhubd.h>
    29 #include <usb_iface.h>
    30 #include <usb/debug.h>
     28
     29/** @addtogroup drvusbmid
     30 * @{
     31 */
     32/**
     33 * @file
     34 * Main routines of USB multi interface device driver.
     35 */
    3136#include <errno.h>
    3237#include <str_error.h>
    33 #include <driver.h>
    34 #include "uhci.h"
     38#include <usb/debug.h>
     39#include <usb/classes/classes.h>
     40#include <usb/request.h>
     41#include <usb/descriptor.h>
     42#include <usb/pipes.h>
    3543
    36 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
     44#include "usbmid.h"
     45
     46static int usbmid_add_device(ddf_dev_t *gen_dev)
    3747{
    38         /* This shall be called only for the UHCI itself. */
    39         assert(dev->parent == NULL);
     48        usbmid_device_t *dev = usbmid_device_create(gen_dev);
     49        if (dev == NULL) {
     50                return ENOMEM;
     51        }
    4052
    41         *handle = dev->handle;
     53        usb_log_info("Taking care of new MID: addr %d (HC %zu)\n",
     54            dev->wire.address, dev->wire.hc_handle);
     55
     56        int rc;
     57
     58        rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe);
     59        if (rc != EOK) {
     60                usb_log_error("Failed to start session on control pipe: %s.\n",
     61                    str_error(rc));
     62                goto error_leave;
     63        }
     64
     65        bool accept = usbmid_explore_device(dev);
     66
     67        rc = usb_endpoint_pipe_end_session(&dev->ctrl_pipe);
     68        if (rc != EOK) {
     69                usb_log_warning("Failed to end session on control pipe: %s.\n",
     70                    str_error(rc));
     71        }
     72
     73        if (!accept) {
     74                rc = ENOTSUP;
     75                goto error_leave;
     76        }
     77
     78        gen_dev->driver_data = dev;
     79
    4280        return EOK;
     81
     82
     83error_leave:
     84        free(dev);
     85        return rc;
    4386}
    4487
    45 static usb_iface_t hc_usb_iface = {
    46         .get_hc_handle = usb_iface_get_hc_handle
     88static driver_ops_t mid_driver_ops = {
     89        .add_device = usbmid_add_device,
    4790};
    4891
    49 static device_ops_t uhci_ops = {
    50         .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    51         .interfaces[USBHC_DEV_IFACE] = &uhci_iface
    52 };
    53 
    54 static int uhci_add_device(device_t *device)
    55 {
    56         usb_dprintf(NAME, 1, "uhci_add_device() called\n");
    57         device->ops = &uhci_ops;
    58 
    59         uintptr_t io_reg_base;
    60         size_t io_reg_size;
    61         int irq;
    62 
    63         int rc = pci_get_my_registers(device,
    64             &io_reg_base, &io_reg_size, &irq);
    65 
    66         if (rc != EOK) {
    67                 fprintf(stderr,
    68                     NAME ": failed to get I/O registers addresses: %s.\n",
    69                     str_error(rc));
    70                 return rc;
    71         }
    72 
    73         usb_dprintf(NAME, 2, "I/O regs at 0x%X (size %zu), IRQ %d.\n",
    74             io_reg_base, io_reg_size, irq);
    75 
    76         /*
    77          * We need to announce the presence of our root hub.
    78          */
    79         usb_dprintf(NAME, 2, "adding root hub\n");
    80         usb_hcd_add_root_hub(device);
    81 
    82         return EOK;
    83 }
    84 
    85 static driver_ops_t uhci_driver_ops = {
    86         .add_device = uhci_add_device,
    87 };
    88 
    89 static driver_t uhci_driver = {
     92static driver_t mid_driver = {
    9093        .name = NAME,
    91         .driver_ops = &uhci_driver_ops
     94        .driver_ops = &mid_driver_ops
    9295};
    9396
    9497int main(int argc, char *argv[])
    9598{
    96         /*
    97          * Do some global initializations.
    98          */
    99         sleep(5);
    100         usb_dprintf_enable(NAME, 5);
     99        printf(NAME ": USB multi interface device driver.\n");
    101100
    102         return driver_main(&uhci_driver);
     101        usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     102        return ddf_driver_main(&mid_driver);
    103103}
     104
     105/**
     106 * @}
     107 */
  • uspace/drv/vhc/conn.h

    r4837092 r92574f4  
    3737
    3838#include <usb/usb.h>
    39 #include <usb/hcdhubd.h>
    4039#include <usbhc_iface.h>
     40#include <usb_iface.h>
    4141#include "vhcd.h"
    4242#include "devices.h"
     
    4444void connection_handler_host(sysarg_t);
    4545
    46 usb_hcd_transfer_ops_t vhc_transfer_ops;
    47 usbhc_iface_t vhc_iface;
     46extern usbhc_iface_t vhc_iface;
     47extern usb_iface_t vhc_usb_iface;
     48extern usb_iface_t rh_usb_iface;
    4849
    4950void address_init(void);
    5051
    5152
    52 void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *);
    53 void on_client_close(device_t *);
     53void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     54void on_client_close(ddf_fun_t *);
    5455
    5556
  • uspace/drv/vhc/conndev.c

    r4837092 r92574f4  
    7676/** Default handler for IPC methods not handled by DDF.
    7777 *
    78  * @param dev Device handling the call.
     78 * @param fun Device handling the call.
    7979 * @param icallid Call id.
    8080 * @param icall Call data.
    8181 */
    82 void default_connection_handler(device_t *dev,
     82void default_connection_handler(ddf_fun_t *fun,
    8383    ipc_callid_t icallid, ipc_call_t *icall)
    8484{
     
    9090                    = virtdev_add_device(callback, (sysarg_t)fibril_get_id());
    9191                if (!dev) {
    92                         ipc_answer_0(icallid, EEXISTS);
    93                         ipc_hangup(callback);
     92                        async_answer_0(icallid, EEXISTS);
     93                        async_hangup(callback);
    9494                        return;
    9595                }
    96                 ipc_answer_0(icallid, EOK);
     96                async_answer_0(icallid, EOK);
    9797
    9898                char devname[DEVICE_NAME_MAXLENGTH + 1];
     
    105105        }
    106106
    107         ipc_answer_0(icallid, EINVAL);
     107        async_answer_0(icallid, EINVAL);
    108108}
    109109
     
    112112 * @param d Device the client was connected to.
    113113 */
    114 void on_client_close(device_t *d)
     114void on_client_close(ddf_fun_t *fun)
    115115{
    116116        /*
  • uspace/drv/vhc/connhost.c

    r4837092 r92574f4  
    3636#include <errno.h>
    3737#include <usb/usb.h>
    38 #include <usb/hcd.h>
     38#include <usb/addrkeep.h>
     39#include <usb/ddfiface.h>
    3940
    4041#include "vhcd.h"
     
    4748        usbhc_iface_transfer_out_callback_t out_callback;
    4849        usbhc_iface_transfer_in_callback_t in_callback;
    49         device_t *dev;
     50        ddf_fun_t *fun;
    5051        size_t reported_size;
    5152        void *arg;
     
    5758        usbhc_iface_transfer_out_callback_t out_callback;
    5859        usbhc_iface_transfer_in_callback_t in_callback;
    59         device_t *dev;
     60        ddf_fun_t *fun;
    6061        void *arg;
    6162        void *data_buffer;
     
    6465
    6566static void universal_callback(void *buffer, size_t size,
    66     usb_transaction_outcome_t outcome, void *arg)
     67    int outcome, void *arg)
    6768{
    6869        transfer_info_t *transfer = (transfer_info_t *) arg;
     
    7475        switch (transfer->direction) {
    7576                case USB_DIRECTION_IN:
    76                         transfer->in_callback(transfer->dev,
     77                        transfer->in_callback(transfer->fun,
    7778                            outcome, size,
    7879                            transfer->arg);
    7980                        break;
    8081                case USB_DIRECTION_OUT:
    81                         transfer->out_callback(transfer->dev,
     82                        transfer->out_callback(transfer->fun,
    8283                            outcome,
    8384                            transfer->arg);
     
    9192}
    9293
    93 static transfer_info_t *create_transfer_info(device_t *dev,
     94static transfer_info_t *create_transfer_info(ddf_fun_t *fun,
    9495    usb_direction_t direction, void *arg)
    9596{
     
    100101        transfer->out_callback = NULL;
    101102        transfer->arg = arg;
    102         transfer->dev = dev;
     103        transfer->fun = fun;
    103104        transfer->reported_size = (size_t) -1;
    104105
     
    107108
    108109static void control_abort_prematurely(control_transfer_info_t *transfer,
    109     size_t size, usb_transaction_outcome_t outcome)
     110    size_t size, int outcome)
    110111{
    111112        switch (transfer->direction) {
    112113                case USB_DIRECTION_IN:
    113                         transfer->in_callback(transfer->dev,
     114                        transfer->in_callback(transfer->fun,
    114115                            outcome, size,
    115116                            transfer->arg);
    116117                        break;
    117118                case USB_DIRECTION_OUT:
    118                         transfer->out_callback(transfer->dev,
     119                        transfer->out_callback(transfer->fun,
    119120                            outcome,
    120121                            transfer->arg);
     
    127128
    128129static void control_callback_two(void *buffer, size_t size,
    129     usb_transaction_outcome_t outcome, void *arg)
     130    int outcome, void *arg)
    130131{
    131132        control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg;
    132133
    133         if (outcome != USB_OUTCOME_OK) {
     134        if (outcome != EOK) {
    134135                control_abort_prematurely(ctrl_transfer, outcome, size);
    135136                free(ctrl_transfer);
     
    137138        }
    138139
    139         transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->dev,
     140        transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->fun,
    140141            ctrl_transfer->direction, ctrl_transfer->arg);
    141142        transfer->out_callback = ctrl_transfer->out_callback;
     
    165166
    166167static void control_callback_one(void *buffer, size_t size,
    167     usb_transaction_outcome_t outcome, void *arg)
     168    int outcome, void *arg)
    168169{
    169170        control_transfer_info_t *transfer = (control_transfer_info_t *) arg;
    170171
    171         if (outcome != USB_OUTCOME_OK) {
     172        if (outcome != EOK) {
    172173                control_abort_prematurely(transfer, outcome, size);
    173174                free(transfer);
     
    194195}
    195196
    196 static control_transfer_info_t *create_control_transfer_info(device_t *dev,
     197static control_transfer_info_t *create_control_transfer_info(ddf_fun_t *fun,
    197198    usb_direction_t direction, usb_target_t target,
    198199    void *data_buffer, size_t data_buffer_size,
     
    207208        transfer->out_callback = NULL;
    208209        transfer->arg = arg;
    209         transfer->dev = dev;
     210        transfer->fun = fun;
    210211        transfer->data_buffer = data_buffer;
    211212        transfer->data_buffer_size = data_buffer_size;
     
    214215}
    215216
    216 static int enqueue_transfer_out(device_t *dev,
     217static int enqueue_transfer_out(ddf_fun_t *fun,
    217218    usb_target_t target, usb_transfer_type_t transfer_type,
    218219    void *buffer, size_t size,
     
    225226
    226227        transfer_info_t *transfer
    227             = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
     228            = create_transfer_info(fun, USB_DIRECTION_OUT, arg);
    228229        transfer->out_callback = callback;
    229230
     
    234235}
    235236
    236 static int enqueue_transfer_setup(device_t *dev,
    237     usb_target_t target, usb_transfer_type_t transfer_type,
    238     void *buffer, size_t size,
    239     usbhc_iface_transfer_out_callback_t callback, void *arg)
    240 {
    241         usb_log_debug2("Transfer SETUP [%d.%d (%s); %zu].\n",
    242             target.address, target.endpoint,
    243             usb_str_transfer_type(transfer_type),
    244             size);
    245 
    246         transfer_info_t *transfer
    247             = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
    248         transfer->out_callback = callback;
    249 
    250         hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
    251             universal_callback, transfer);
    252 
    253         return EOK;
    254 }
    255 
    256 static int enqueue_transfer_in(device_t *dev,
     237static int enqueue_transfer_in(ddf_fun_t *fun,
    257238    usb_target_t target, usb_transfer_type_t transfer_type,
    258239    void *buffer, size_t size,
     
    265246
    266247        transfer_info_t *transfer
    267             = create_transfer_info(dev, USB_DIRECTION_IN, arg);
     248            = create_transfer_info(fun, USB_DIRECTION_IN, arg);
    268249        transfer->in_callback = callback;
    269250
     
    275256
    276257
    277 static int interrupt_out(device_t *dev, usb_target_t target,
     258static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
     259    size_t max_packet_size,
    278260    void *data, size_t size,
    279261    usbhc_iface_transfer_out_callback_t callback, void *arg)
    280262{
    281         return enqueue_transfer_out(dev, target, USB_TRANSFER_INTERRUPT,
     263        return enqueue_transfer_out(fun, target, USB_TRANSFER_INTERRUPT,
    282264            data, size,
    283265            callback, arg);
    284266}
    285267
    286 static int interrupt_in(device_t *dev, usb_target_t target,
     268static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
     269    size_t max_packet_size,
    287270    void *data, size_t size,
    288271    usbhc_iface_transfer_in_callback_t callback, void *arg)
    289272{
    290         return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
     273        return enqueue_transfer_in(fun, target, USB_TRANSFER_INTERRUPT,
    291274            data, size,
    292275            callback, arg);
    293276}
    294277
    295 static int control_write_setup(device_t *dev, usb_target_t target,
    296     void *data, size_t size,
    297     usbhc_iface_transfer_out_callback_t callback, void *arg)
    298 {
    299         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    300             data, size,
    301             callback, arg);
    302 }
    303 
    304 static int control_write_data(device_t *dev, usb_target_t target,
    305     void *data, size_t size,
    306     usbhc_iface_transfer_out_callback_t callback, void *arg)
    307 {
    308         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    309             data, size,
    310             callback, arg);
    311 }
    312 
    313 static int control_write_status(device_t *dev, usb_target_t target,
    314     usbhc_iface_transfer_in_callback_t callback, void *arg)
    315 {
    316         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    317             NULL, 0,
    318             callback, arg);
    319 }
    320 
    321 static int control_write(device_t *dev, usb_target_t target,
     278static int control_write(ddf_fun_t *fun, usb_target_t target,
     279    size_t max_packet_size,
    322280    void *setup_packet, size_t setup_packet_size,
    323281    void *data, size_t data_size,
     
    325283{
    326284        control_transfer_info_t *transfer
    327             = create_control_transfer_info(dev, USB_DIRECTION_OUT, target,
     285            = create_control_transfer_info(fun, USB_DIRECTION_OUT, target,
    328286            data, data_size, arg);
    329287        transfer->out_callback = callback;
     
    336294}
    337295
    338 static int control_read_setup(device_t *dev, usb_target_t target,
    339     void *data, size_t size,
    340     usbhc_iface_transfer_out_callback_t callback, void *arg)
    341 {
    342         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    343             data, size,
    344             callback, arg);
    345 }
    346 
    347 static int control_read_data(device_t *dev, usb_target_t target,
    348     void *data, size_t size,
    349     usbhc_iface_transfer_in_callback_t callback, void *arg)
    350 {
    351         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    352             data, size,
    353             callback, arg);
    354 }
    355 
    356 static int control_read_status(device_t *dev, usb_target_t target,
    357     usbhc_iface_transfer_out_callback_t callback, void *arg)
    358 {
    359         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    360             NULL, 0,
    361             callback, arg);
    362 }
    363 
    364 static int control_read(device_t *dev, usb_target_t target,
     296static int control_read(ddf_fun_t *fun, usb_target_t target,
     297    size_t max_packet_size,
    365298    void *setup_packet, size_t setup_packet_size,
    366299    void *data, size_t data_size,
     
    368301{
    369302        control_transfer_info_t *transfer
    370             = create_control_transfer_info(dev, USB_DIRECTION_IN, target,
     303            = create_control_transfer_info(fun, USB_DIRECTION_IN, target,
    371304            data, data_size, arg);
    372305        transfer->in_callback = callback;
     
    381314static usb_address_keeping_t addresses;
    382315
    383 
    384 static int reserve_default_address(device_t *dev)
     316static int tell_address(ddf_fun_t *fun, devman_handle_t handle,
     317    usb_address_t *address)
     318{
     319        usb_log_debug("tell_address(fun \"%s\", handle %zu)\n",
     320            fun->name, (size_t) fun->handle);
     321        usb_address_t addr = usb_address_keeping_find(&addresses, handle);
     322        if (addr < 0) {
     323                return addr;
     324        }
     325
     326        *address = addr;
     327        return EOK;
     328}
     329
     330static int reserve_default_address(ddf_fun_t *fun, usb_speed_t ignored)
    385331{
    386332        usb_address_keeping_reserve_default(&addresses);
     
    388334}
    389335
    390 static int release_default_address(device_t *dev)
     336static int release_default_address(ddf_fun_t *fun)
    391337{
    392338        usb_address_keeping_release_default(&addresses);
     
    394340}
    395341
    396 static int request_address(device_t *dev, usb_address_t *address)
     342static int request_address(ddf_fun_t *fun, usb_speed_t ignored,
     343    usb_address_t *address)
    397344{
    398345        usb_address_t addr = usb_address_keeping_request(&addresses);
     
    405352}
    406353
    407 static int release_address(device_t *dev, usb_address_t address)
     354static int release_address(ddf_fun_t *fun, usb_address_t address)
    408355{
    409356        return usb_address_keeping_release(&addresses, address);
    410357}
    411358
    412 static int bind_address(device_t *dev, usb_address_t address,
     359static int bind_address(ddf_fun_t *fun, usb_address_t address,
    413360    devman_handle_t handle)
    414361{
     
    417364}
    418365
    419 static int tell_address(device_t *dev, devman_handle_t handle,
     366static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
     367    devman_handle_t *handle)
     368{
     369        ddf_fun_t *hc_fun = root_hub_fun->driver_data;
     370        assert(hc_fun != NULL);
     371
     372        *handle = hc_fun->handle;
     373
     374        usb_log_debug("usb_iface_get_hc_handle_rh_impl returns %zu\n", *handle);
     375
     376        return EOK;
     377}
     378
     379static int tell_address_rh(ddf_fun_t *root_hub_fun, devman_handle_t handle,
    420380    usb_address_t *address)
    421381{
    422         usb_address_t addr = usb_address_keeping_find(&addresses, handle);
    423         if (addr < 0) {
    424                 return addr;
    425         }
    426 
    427         *address = addr;
    428         return EOK;
     382        ddf_fun_t *hc_fun = root_hub_fun->driver_data;
     383        assert(hc_fun != NULL);
     384
     385        return tell_address(hc_fun, root_hub_fun->handle, address);
    429386}
    430387
     
    435392
    436393usbhc_iface_t vhc_iface = {
    437         .tell_address = tell_address,
    438 
    439394        .reserve_default_address = reserve_default_address,
    440395        .release_default_address = release_default_address,
     
    446401        .interrupt_in = interrupt_in,
    447402
    448         .control_write_setup = control_write_setup,
    449         .control_write_data = control_write_data,
    450         .control_write_status = control_write_status,
    451 
    452403        .control_write = control_write,
    453 
    454         .control_read_setup = control_read_setup,
    455         .control_read_data = control_read_data,
    456         .control_read_status = control_read_status,
    457 
    458404        .control_read = control_read
    459405};
     406
     407usb_iface_t vhc_usb_iface = {
     408        .get_hc_handle = usb_iface_get_hc_handle_hc_impl,
     409        .get_address = tell_address
     410};
     411
     412usb_iface_t rh_usb_iface = {
     413        .get_hc_handle = usb_iface_get_hc_handle_rh_impl,
     414        .get_address = tell_address_rh
     415};
     416
    460417
    461418/**
  • uspace/drv/vhc/devices.c

    r4837092 r92574f4  
    3434 */
    3535
    36 #include <ipc/ipc.h>
    3736#include <adt/list.h>
    3837#include <bool.h>
     
    113112 * @param transaction Transaction to be sent over the bus.
    114113 */
    115 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *transaction)
     114int virtdev_send_to_all(transaction_t *transaction)
    116115{
    117116        /* For easier debugging. */
     
    127126                        assert(false && "unreachable branch in switch()");
    128127        }
    129         usb_transaction_outcome_t outcome = USB_OUTCOME_BABBLE;
     128        int outcome = EBADCHECKSUM;
    130129
    131130        link_t *pos;
     
    186185                 */
    187186                if (rc == EOK) {
    188                         outcome = USB_OUTCOME_OK;
     187                        outcome = EOK;
    189188                }
    190189        }
     
    222221                                break;
    223222                }
    224                 outcome = USB_OUTCOME_OK;
     223                outcome = EOK;
    225224        }
    226225       
  • uspace/drv/vhc/devices.h

    r4837092 r92574f4  
    5454virtdev_connection_t *virtdev_find(sysarg_t);
    5555void virtdev_destroy_device(virtdev_connection_t *);
    56 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *);
     56int virtdev_send_to_all(transaction_t *);
    5757
    5858#endif
  • uspace/drv/vhc/hc.c

    r4837092 r92574f4  
    3434 */
    3535
    36 #include <ipc/ipc.h>
    3736#include <adt/list.h>
    3837#include <bool.h>
     
    9089 */
    9190static void process_transaction_with_outcome(transaction_t * transaction,
    92     usb_transaction_outcome_t outcome)
     91    int outcome)
    9392{
    9493        usb_log_debug2("Transaction " TRANSACTION_FORMAT " done: %s.\n",
    9594            TRANSACTION_PRINTF(*transaction),
    96             usb_str_transaction_outcome(outcome));
     95            str_error(outcome));
    9796       
    9897        transaction->callback(transaction->buffer, transaction->actual_len,
     
    128127                    TRANSACTION_PRINTF(*transaction), ports);
    129128
    130                 usb_transaction_outcome_t outcome;
     129                int outcome;
    131130                outcome = virtdev_send_to_all(transaction);
    132131               
  • uspace/drv/vhc/hc.h

    r4837092 r92574f4  
    4747 */
    4848typedef void (*hc_transaction_done_callback_t)(void *buffer, size_t size,
    49     usb_transaction_outcome_t outcome, void *arg);
     49    int outcome, void *arg);
    5050
    5151/** Pending transaction details. */
  • uspace/drv/vhc/hcd.c

    r4837092 r92574f4  
    3535
    3636#include <devmap.h>
    37 #include <ipc/ipc.h>
    3837#include <async.h>
    3938#include <unistd.h>
     
    4342#include <errno.h>
    4443#include <str_error.h>
    45 #include <driver.h>
     44#include <ddf/driver.h>
    4645
    4746#include <usb/usb.h>
     47#include <usb/ddfiface.h>
    4848#include <usb_iface.h>
    4949#include "vhcd.h"
     
    5353#include "conn.h"
    5454
    55 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
    56 {
    57         /* This shall be called only for VHC device. */
    58         assert(dev->parent == NULL);
    59 
    60         *handle = dev->handle;
    61         return EOK;
    62 }
    63 
    64 static usb_iface_t hc_usb_iface = {
    65         .get_hc_handle = usb_iface_get_hc_handle
    66 };
    67 
    68 static device_ops_t vhc_ops = {
     55static ddf_dev_ops_t vhc_ops = {
    6956        .interfaces[USBHC_DEV_IFACE] = &vhc_iface,
    70         .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
     57        .interfaces[USB_DEV_IFACE] = &vhc_usb_iface,
    7158        .close = on_client_close,
    7259        .default_handler = default_connection_handler
    7360};
    7461
    75 static int vhc_count = 0;
    76 static int vhc_add_device(device_t *dev)
     62static int vhc_add_device(ddf_dev_t *dev)
    7763{
     64        static int vhc_count = 0;
     65        int rc;
     66
    7867        /*
    7968         * Currently, we know how to simulate only single HC.
     
    8372        }
    8473
    85         vhc_count++;
     74        /*
     75         * Create exposed function representing the host controller
     76         * itself.
     77         */
     78        ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
     79        if (hc == NULL) {
     80                usb_log_fatal("Failed to create device function.\n");
     81                return ENOMEM;
     82        }
    8683
    87         dev->ops = &vhc_ops;
     84        hc->ops = &vhc_ops;
    8885
    89         devman_add_device_to_class(dev->handle, "usbhc");
     86        rc = ddf_fun_bind(hc);
     87        if (rc != EOK) {
     88                usb_log_fatal("Failed to bind HC function: %s.\n",
     89                    str_error(rc));
     90                return rc;
     91        }
     92
     93        ddf_fun_add_to_class(hc, "usbhc");
    9094
    9195        /*
    9296         * Initialize our hub and announce its presence.
    9397         */
    94         virtual_hub_device_init(dev);
     98        virtual_hub_device_init(hc);
    9599
    96         usb_log_info("Virtual USB host controller ready (id = %zu).\n",
    97             (size_t) dev->handle);
     100        usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
     101            (size_t) dev->handle, (size_t) hc->handle);
    98102
    99103        return EOK;
     
    116120         * in devman output.
    117121         */
    118         sleep(5);
     122        //sleep(5);
    119123
    120         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     124        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    121125
    122126        printf(NAME ": virtual USB host controller driver.\n");
     
    135139         * We are also a driver within devman framework.
    136140         */
    137         return driver_main(&vhc_driver);
     141        return ddf_driver_main(&vhc_driver);
    138142}
    139143
  • uspace/drv/vhc/hub.c

    r4837092 r92574f4  
    3939#include <str_error.h>
    4040#include <stdlib.h>
    41 #include <driver.h>
    42 #include <usb/usbdrv.h>
     41#include <ddf/driver.h>
     42#include <devman.h>
     43#include <usb/hub.h>
     44#include <usb/recognise.h>
    4345
    4446#include "hub.h"
    4547#include "hub/virthub.h"
    4648#include "vhcd.h"
     49#include "conn.h"
    4750
    4851usbvirt_device_t virtual_hub_device;
     52static ddf_dev_ops_t rh_ops = {
     53        .interfaces[USB_DEV_IFACE] = &rh_usb_iface,
     54};
    4955
    5056static int hub_register_in_devman_fibril(void *arg);
    5157
    52 void virtual_hub_device_init(device_t *hc_dev)
     58void virtual_hub_device_init(ddf_fun_t *hc_dev)
    5359{
    5460        virthub_init(&virtual_hub_device);
     
    7076}
    7177
     78static int pretend_port_rest(int unused, void *unused2)
     79{
     80        return EOK;
     81}
     82
    7283/** Register root hub in devman.
    7384 *
     
    7788int hub_register_in_devman_fibril(void *arg)
    7889{
    79         device_t *hc_dev = (device_t *) arg;
     90        ddf_fun_t *hc_dev = (ddf_fun_t *) arg;
    8091
    81         int hc;
     92        /*
     93         * Wait until parent device is properly initialized.
     94         */
     95        int phone;
    8296        do {
    83                 hc = usb_drv_hc_connect(hc_dev, hc_dev->handle,
    84                     IPC_FLAG_BLOCKING);
    85         } while (hc < 0);
     97                phone = devman_device_connect(hc_dev->handle, 0);
     98        } while (phone < 0);
     99        async_hangup(phone);
    86100
    87         usb_drv_reserve_default_address(hc);
     101        int rc;
    88102
    89         usb_address_t hub_address = usb_drv_request_address(hc);
    90         usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, hub_address);
     103        usb_hc_connection_t hc_conn;
     104        rc = usb_hc_connection_initialize(&hc_conn, hc_dev->handle);
     105        assert(rc == EOK);
    91106
    92         usb_drv_release_default_address(hc);
     107        rc = usb_hc_connection_open(&hc_conn);
     108        assert(rc == EOK);
    93109
    94         devman_handle_t hub_handle;
    95         usb_drv_register_child_in_devman(hc, hc_dev, hub_address, &hub_handle);
    96         usb_drv_bind_address(hc, hub_address, hub_handle);
     110        ddf_fun_t *hub_dev;
     111        rc = usb_hc_new_device_wrapper(hc_dev->dev, &hc_conn,
     112            USB_SPEED_FULL,
     113            pretend_port_rest, 0, NULL,
     114            NULL, NULL, &rh_ops, hc_dev, &hub_dev);
     115        if (rc != EOK) {
     116                usb_log_fatal("Failed to create root hub: %s.\n",
     117                    str_error(rc));
     118        }
    97119
    98         return EOK;
     120        usb_hc_connection_close(&hc_conn);
     121
     122        usb_log_info("Created root hub function (handle %zu).\n",
     123            (size_t) hub_dev->handle);
     124
     125        return 0;
    99126}
    100127       
  • uspace/drv/vhc/hub.h

    r4837092 r92574f4  
    3737
    3838#include <usbvirt/device.h>
    39 #include <driver.h>
     39#include <ddf/driver.h>
    4040
    4141#include "devices.h"
     
    4545extern usbvirt_device_t virtual_hub_device;
    4646
    47 void virtual_hub_device_init(device_t *);
     47void virtual_hub_device_init(ddf_fun_t *);
    4848
    4949#endif
  • uspace/drv/vhc/hub/hub.c

    r4837092 r92574f4  
    3838#include <errno.h>
    3939#include <str_error.h>
     40#include <assert.h>
    4041#include <stdlib.h>
    41 #include <driver.h>
    42 #include <usb/usbdrv.h>
     42#include <ddf/driver.h>
    4343
    4444#include "hub.h"
  • uspace/drv/vhc/hub/virthub.c

    r4837092 r92574f4  
    3939#include <errno.h>
    4040#include <str_error.h>
     41#include <assert.h>
    4142#include <stdlib.h>
    42 #include <driver.h>
    43 #include <usb/usbdrv.h>
     43#include <ddf/driver.h>
    4444
    4545#include "virthub.h"
Note: See TracChangeset for help on using the changeset viewer.