Changeset 19a1800 in mainline for uspace/drv


Ignore:
Timestamp:
2011-03-01T22:20:56Z (15 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e24e7b1
Parents:
976f546 (diff), ac8285d (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:

Merge with the current development

Location:
uspace/drv
Files:
46 added
2 deleted
37 edited
8 moved

Legend:

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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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);
     322
     323#define IO_MASK  (~0x3)
     324#define MEM_MASK (~0xf)
    288325       
    289326        io = (bool) (val & 1);
    290327        if (io) {
    291328                addrw64 = false;
     329                mask = IO_MASK;
    292330        } else {
     331                mask = MEM_MASK;
    293332                switch ((val >> 1) & 3) {
    294333                case 0:
     
    305344       
    306345        /* Get the address mask. */
    307         pci_conf_write_32(dev, addr, 0xffffffff);
    308         mask = pci_conf_read_32(dev, addr);
     346        pci_conf_write_32(fun, addr, 0xffffffff);
     347        mask &= pci_conf_read_32(fun, addr);
    309348       
    310349        /* Restore the original value. */
    311         pci_conf_write_32(dev, addr, val);
    312         val = pci_conf_read_32(dev, addr);
     350        pci_conf_write_32(fun, addr, val);
     351        val = pci_conf_read_32(fun, addr);
    313352       
    314353        range_size = pci_bar_mask_to_size(mask);
    315354       
    316355        if (addrw64) {
    317                 range_addr = ((uint64_t)pci_conf_read_32(dev, addr + 4) << 32) |
     356                range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) |
    318357                    (val & 0xfffffff0);
    319358        } else {
     
    322361       
    323362        if (range_addr != 0) {
    324                 printf(NAME ": device %s : ", dev->name);
     363                printf(NAME ": function %s : ", fun->fnode->name);
    325364                printf("address = %" PRIx64, range_addr);
    326365                printf(", size = %x\n", (unsigned int) range_size);
    327366        }
    328367       
    329         pci_add_range(dev, range_addr, range_size, io);
     368        pci_add_range(fun, range_addr, range_size, io);
    330369       
    331370        if (addrw64)
     
    335374}
    336375
    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;
     376void pci_add_interrupt(pci_fun_t *fun, int irq)
     377{
     378        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    341379        hw_resource_t *hw_resources = hw_res_list->resources;
    342380        size_t count = hw_res_list->count;
     
    350388        hw_res_list->count++;
    351389       
    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);
     390        printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq);
     391}
     392
     393void pci_read_interrupt(pci_fun_t *fun)
     394{
     395        uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
    358396        if (irq != 0xff)
    359                 pci_add_interrupt(dev, irq);
     397                pci_add_interrupt(fun, irq);
    360398}
    361399
    362400/** Enumerate (recursively) and register the devices connected to a pci bus.
    363401 *
    364  * @param parent        The host-to-pci bridge device.
    365  * @param bus_num       The bus number.
     402 * @param bus           Host-to-PCI bridge
     403 * @param bus_num       Bus number
    366404 */
    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;
     405void pci_bus_scan(pci_bus_t *bus, int bus_num)
     406{
     407        ddf_fun_t *fnode;
     408        pci_fun_t *fun;
    373409       
    374410        int child_bus = 0;
    375411        int dnum, fnum;
    376412        bool multi;
    377         uint8_t header_type;
     413        uint8_t header_type;
     414       
     415        fun = pci_fun_new(bus);
    378416       
    379417        for (dnum = 0; dnum < 32; dnum++) {
    380418                multi = true;
    381419                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,
     420                        pci_fun_init(fun, bus_num, dnum, fnum);
     421                        fun->vendor_id = pci_conf_read_16(fun,
    384422                            PCI_VENDOR_ID);
    385                         dev_data->device_id = pci_conf_read_16(dev,
     423                        fun->device_id = pci_conf_read_16(fun,
    386424                            PCI_DEVICE_ID);
    387                         if (dev_data->vendor_id == 0xffff) {
     425                        if (fun->vendor_id == 0xffff) {
    388426                                /*
    389427                                 * The device is not present, go on scanning the
     
    396434                        }
    397435                       
    398                         header_type = pci_conf_read_8(dev, PCI_HEADER_TYPE);
     436                        header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE);
    399437                        if (fnum == 0) {
    400438                                /* Is the device multifunction? */
     
    404442                        header_type = header_type & 0x7F;
    405443                       
    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;
     444                        char *fun_name = pci_fun_create_name(fun);
     445                        if (fun_name == NULL) {
     446                                printf(NAME ": out of memory.\n");
     447                                return;
     448                        }
     449                       
     450                        fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
     451                        if (fnode == NULL) {
     452                                printf(NAME ": error creating function.\n");
     453                                return;
     454                        }
     455                       
     456                        free(fun_name);
     457                        fun->fnode = fnode;
     458                       
     459                        pci_alloc_resource_list(fun);
     460                        pci_read_bars(fun);
     461                        pci_read_interrupt(fun);
     462                       
     463                        fnode->ops = &pci_fun_ops;
     464                        fnode->driver_data = fun;
     465                       
     466                        printf(NAME ": adding new function %s.\n",
     467                            fnode->name);
     468                       
     469                        pci_fun_create_match_ids(fun);
     470                       
     471                        if (ddf_fun_bind(fnode) != EOK) {
     472                                pci_clean_resource_list(fun);
     473                                clean_match_ids(&fnode->match_ids);
     474                                free((char *) fnode->name);
     475                                fnode->name = NULL;
    424476                                continue;
    425477                        }
     
    427479                        if (header_type == PCI_HEADER_TYPE_BRIDGE ||
    428480                            header_type == PCI_HEADER_TYPE_CARDBUS) {
    429                                 child_bus = pci_conf_read_8(dev,
     481                                child_bus = pci_conf_read_8(fun,
    430482                                    PCI_BRIDGE_SEC_BUS_NUM);
    431483                                printf(NAME ": device is pci-to-pci bridge, "
    432484                                    "secondary bus number = %d.\n", bus_num);
    433485                                if (child_bus > bus_num)
    434                                         pci_bus_scan(parent, child_bus);
     486                                        pci_bus_scan(bus, child_bus);
    435487                        }
    436488                       
    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;
     489                        fun = pci_fun_new(bus);
    442490                }
    443491        }
    444492       
    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 {
     493        if (fun->vendor_id == 0xffff) {
     494                /* Free the auxiliary function structure. */
     495                pci_fun_delete(fun);
     496        }
     497}
     498
     499static int pci_add_device(ddf_dev_t *dnode)
     500{
     501        pci_bus_t *bus = NULL;
     502        ddf_fun_t *ctl = NULL;
     503        bool got_res = false;
    454504        int rc;
    455 
     505       
    456506        printf(NAME ": pci_add_device\n");
    457        
    458         pci_bus_data_t *bus_data = create_pci_bus_data();
    459         if (bus_data == NULL) {
     507        dnode->parent_phone = -1;
     508       
     509        bus = pci_bus_new();
     510        if (bus == NULL) {
    460511                printf(NAME ": pci_add_device allocation failed.\n");
    461                 return ENOMEM;
    462         }
    463        
    464         dev->parent_phone = devman_parent_device_connect(dev->handle,
     512                rc = ENOMEM;
     513                goto fail;
     514        }
     515        bus->dnode = dnode;
     516        dnode->driver_data = bus;
     517       
     518        dnode->parent_phone = devman_parent_device_connect(dnode->handle,
    465519            IPC_FLAG_BLOCKING);
    466         if (dev->parent_phone < 0) {
     520        if (dnode->parent_phone < 0) {
    467521                printf(NAME ": pci_add_device failed to connect to the "
    468522                    "parent's driver.\n");
    469                 delete_pci_bus_data(bus_data);
    470                 return dev->parent_phone;
     523                rc = dnode->parent_phone;
     524                goto fail;
    471525        }
    472526       
    473527        hw_resource_list_t hw_resources;
    474528       
    475         rc = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
     529        rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
    476530        if (rc != EOK) {
    477531                printf(NAME ": pci_add_device failed to get hw resources for "
    478532                    "the device.\n");
    479                 delete_pci_bus_data(bus_data);
    480                 ipc_hangup(dev->parent_phone);
    481                 return rc;
    482         }       
     533                goto fail;
     534        }
     535        got_res = true;
    483536       
    484537        printf(NAME ": conf_addr = %" PRIx64 ".\n",
     
    489542        assert(hw_resources.resources[0].res.io_range.size == 8);
    490543       
    491         bus_data->conf_io_addr =
     544        bus->conf_io_addr =
    492545            (uint32_t) hw_resources.resources[0].res.io_range.address;
    493546       
    494         if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8,
    495             &bus_data->conf_addr_port)) {
     547        if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
     548            &bus->conf_addr_port)) {
    496549                printf(NAME ": failed to enable configuration ports.\n");
    497                 delete_pci_bus_data(bus_data);
    498                 ipc_hangup(dev->parent_phone);
     550                rc = EADDRNOTAVAIL;
     551                goto fail;
     552        }
     553        bus->conf_data_port = (char *) bus->conf_addr_port + 4;
     554       
     555        /* Make the bus device more visible. It has no use yet. */
     556        printf(NAME ": adding a 'ctl' function\n");
     557       
     558        ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl");
     559        if (ctl == NULL) {
     560                printf(NAME ": error creating control function.\n");
     561                rc = ENOMEM;
     562                goto fail;
     563        }
     564       
     565        rc = ddf_fun_bind(ctl);
     566        if (rc != EOK) {
     567                printf(NAME ": error binding control function.\n");
     568                goto fail;
     569        }
     570       
     571        /* Enumerate functions. */
     572        printf(NAME ": scanning the bus\n");
     573        pci_bus_scan(bus, 0);
     574       
     575        hw_res_clean_resource_list(&hw_resources);
     576       
     577        return EOK;
     578       
     579fail:
     580        if (bus != NULL)
     581                pci_bus_delete(bus);
     582        if (dnode->parent_phone >= 0)
     583                async_hangup(dnode->parent_phone);
     584        if (got_res)
    499585                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;
     586        if (ctl != NULL)
     587                ddf_fun_destroy(ctl);
     588
     589        return rc;
    513590}
    514591
    515592static void pciintel_init(void)
    516593{
    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;
     594        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     595}
     596
     597pci_fun_t *pci_fun_new(pci_bus_t *bus)
     598{
     599        pci_fun_t *fun;
     600       
     601        fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
     602        if (fun == NULL)
     603                return NULL;
     604
     605        fun->busptr = bus;
     606        return fun;
     607}
     608
     609void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn)
     610{
     611        fun->bus = bus;
     612        fun->dev = dev;
     613        fun->fn = fn;
     614}
     615
     616void pci_fun_delete(pci_fun_t *fun)
     617{
     618        assert(fun != NULL);
     619        hw_res_clean_resource_list(&fun->hw_resources);
     620        free(fun);
     621}
     622
     623char *pci_fun_create_name(pci_fun_t *fun)
     624{
    547625        char *name = NULL;
    548626       
    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 =
     627        asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev,
     628            fun->fn);
     629        return name;
     630}
     631
     632bool pci_alloc_resource_list(pci_fun_t *fun)
     633{
     634        fun->hw_resources.resources =
    559635            (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.
     636        return fun->hw_resources.resources != NULL;
     637}
     638
     639void pci_clean_resource_list(pci_fun_t *fun)
     640{
     641        if (fun->hw_resources.resources != NULL) {
     642                free(fun->hw_resources.resources);
     643                fun->hw_resources.resources = NULL;
     644        }
     645}
     646
     647/** Read the base address registers (BARs) of the function and add the addresses
     648 * to its HW resource list.
    575649 *
    576  * @param dev the pci device.
     650 * @param fun   PCI function
    577651 */
    578 void pci_read_bars(device_t *dev)
     652void pci_read_bars(pci_fun_t *fun)
    579653{
    580654        /*
     
    585659       
    586660        while (addr <= PCI_BASE_ADDR_5)
    587                 addr = pci_read_bar(dev, addr);
     661                addr = pci_read_bar(fun, addr);
    588662}
    589663
    590664size_t pci_bar_mask_to_size(uint32_t mask)
    591665{
    592         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     666        size_t size = mask & ~(mask - 1);
     667        return size;
    593668}
    594669
     
    597672        printf(NAME ": HelenOS pci bus driver (intel method 1).\n");
    598673        pciintel_init();
    599         return driver_main(&pci_driver);
     674        return ddf_driver_main(&pci_driver);
    600675}
    601676
  • uspace/drv/pciintel/pci.h

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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

    r976f546 r19a1800  
    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/Makefile

    r976f546 r19a1800  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2010 Vojtech Horky
    43# All rights reserved.
    54#
     
    2928
    3029USPACE_PREFIX = ../..
    31 BINARY = tasks
     30LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     32BINARY = uhci-hcd
    3233
    3334SOURCES = \
    34         tasks.c
     35        iface.c \
     36        main.c \
     37        root_hub.c \
     38        transfer_list.c \
     39        uhci.c \
     40        uhci_struct/transfer_descriptor.c \
     41        utils/device_keeper.c \
     42        pci.c \
     43        batch.c
    3544
    3645include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/uhci-hcd/iface.h

    r976f546 r19a1800  
    3333 * @brief UHCI driver
    3434 */
    35 #ifndef DRV_UHCI_UHCI_H
    36 #define DRV_UHCI_UHCI_H
     35#ifndef DRV_UHCI_IFACE_H
     36#define DRV_UHCI_IFACE_H
    3737
    3838#include <usbhc_iface.h>
    3939
    40 #define NAME "uhci"
    41 
    42 usbhc_iface_t uhci_iface;
     40extern usbhc_iface_t uhci_iface;
    4341
    4442#endif
  • uspace/drv/uhci-hcd/pci.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbuhci
    3030 * @{
    3131 */
    3232/** @file
    33  * @brief Debugging support.
     33 * @brief UHCI driver
    3434 */
    35 #include <stdio.h>
    36 #include <ipc/ipc.h>
    37 #include <usb/debug.h>
     35#ifndef DRV_UHCI_PCI_H
     36#define DRV_UHCI_PCI_H
    3837
    39 #include "vhcd.h"
     38#include <ddf/driver.h>
    4039
     40int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
     41int pci_enable_interrupts(ddf_dev_t *);
    4142
    42 /** Debug print informing of invalid call.
    43  */
    44 void dprintf_inval_call(int level, ipc_call_t call, sysarg_t phone_hash)
    45 {
    46         dprintf(level, "phone%#x: invalid call [%u (%u, %u, %u, %u, %u)]",
    47             phone_hash,
    48             IPC_GET_IMETHOD(call),
    49             IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call),
    50             IPC_GET_ARG4(call), IPC_GET_ARG5(call));
    51 }
    52 
     43#endif
    5344/**
    5445 * @}
    5546 */
     47
  • uspace/drv/uhci-rhd/Makefile

    r976f546 r19a1800  
    11#
    2 # Copyright (c) 2010 Vojtech Horky
     2# Copyright (c) 2010 Jan Vesely
    33# All rights reserved.
    44#
     
    2929USPACE_PREFIX = ../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
    32 BINARY = usbkbd
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     32BINARY = uhci-rhd
    3333
    3434SOURCES = \
    35         main.c
     35        main.c \
     36        port.c \
     37        port_status.c \
     38        root_hub.c
    3639
    3740include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/usbhid/main.c

    r976f546 r19a1800  
    11/*
    22 * Copyright (c) 2010 Vojtech Horky
     3 * Copyright (c) 2011 Lubos Slovak
    34 * All rights reserved.
    45 *
     
    2627 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2728 */
    28 #include <usb/hcdhubd.h>
    29 #include <usb_iface.h>
     29
     30/** @addtogroup drvusbhid
     31 * @{
     32 */
     33/**
     34 * @file
     35 * Main routines of USB HID driver.
     36 */
     37
     38#include <ddf/driver.h>
    3039#include <usb/debug.h>
    3140#include <errno.h>
    32 #include <driver.h>
    33 #include "uhci.h"
    3441
    35 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
     42#include "kbddev.h"
     43
     44/*----------------------------------------------------------------------------*/
     45
     46#define NAME "usbhid"
     47
     48/*----------------------------------------------------------------------------*/
     49
     50static int usbhid_add_device(ddf_dev_t *dev)
    3651{
    37         /* This shall be called only for the UHCI itself. */
    38         assert(dev->parent == NULL);
    39 
    40         *handle = dev->handle;
     52        usb_log_debug("usbhid_add_device()\n");
     53       
     54        int rc = usbhid_kbd_try_add_device(dev);
     55       
     56        if (rc != EOK) {
     57                usb_log_info("Device is not a supported keyboard.\n");
     58                usb_log_error("Failed to add HID device.\n");
     59                return EREFUSED;
     60        }
     61       
    4162        return EOK;
    4263}
    4364
    44 static usb_iface_t hc_usb_iface = {
    45         .get_hc_handle = usb_iface_get_hc_handle
     65/*----------------------------------------------------------------------------*/
     66
     67static driver_ops_t kbd_driver_ops = {
     68        .add_device = usbhid_add_device,
    4669};
    4770
    48 static device_ops_t uhci_ops = {
    49         .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    50         .interfaces[USBHC_DEV_IFACE] = &uhci_iface
     71/*----------------------------------------------------------------------------*/
     72
     73static driver_t kbd_driver = {
     74        .name = NAME,
     75        .driver_ops = &kbd_driver_ops
    5176};
    5277
    53 static int uhci_add_device(device_t *device)
    54 {
    55         usb_dprintf(NAME, 1, "uhci_add_device() called\n");
    56         device->ops = &uhci_ops;
    57 
    58         /*
    59          * We need to announce the presence of our root hub.
    60          */
    61         usb_dprintf(NAME, 2, "adding root hub\n");
    62         usb_hcd_add_root_hub(device);
    63 
    64         return EOK;
    65 }
    66 
    67 static driver_ops_t uhci_driver_ops = {
    68         .add_device = uhci_add_device,
    69 };
    70 
    71 static driver_t uhci_driver = {
    72         .name = NAME,
    73         .driver_ops = &uhci_driver_ops
    74 };
     78/*----------------------------------------------------------------------------*/
    7579
    7680int main(int argc, char *argv[])
    7781{
    78         /*
    79          * Do some global initializations.
    80          */
    81         sleep(5);
    82         usb_dprintf_enable(NAME, 5);
     82        usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     83        return ddf_driver_main(&kbd_driver);
     84}
    8385
    84         return driver_main(&uhci_driver);
    85 }
     86/**
     87 * @}
     88 */
  • uspace/drv/usbhub/main.c

    r976f546 r19a1800  
    2727 */
    2828
    29 #include <driver.h>
     29/** @addtogroup drvusbhub
     30 * @{
     31 */
     32
     33#include <ddf/driver.h>
    3034#include <errno.h>
    3135#include <async.h>
    32 
    33 #include <usb/usbdrv.h>
     36#include <stdio.h>
    3437
    3538#include "usbhub.h"
     
    3841
    3942usb_general_list_t usb_hub_list;
    40 futex_t usb_hub_list_lock;
     43fibril_mutex_t usb_hub_list_lock;
    4144
    4245static driver_ops_t hub_driver_ops = {
     
    4952};
    5053
    51 int usb_hub_control_loop(void * noparam){
    52         while(true){
    53                 usb_hub_check_hub_changes();
    54                 async_usleep(1000 * 1000);
    55         }
    56         return 0;
     54int main(int argc, char *argv[])
     55{
     56        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     57        dprintf(USB_LOG_LEVEL_INFO, "starting hub driver");
     58
     59        //this is probably not needed anymore
     60        fibril_mutex_initialize(&usb_hub_list_lock);
     61        fibril_mutex_lock(&usb_hub_list_lock);
     62        usb_lst_init(&usb_hub_list);
     63        fibril_mutex_unlock(&usb_hub_list_lock);
     64       
     65        return ddf_driver_main(&hub_driver);
    5766}
    5867
     68/**
     69 * @}
     70 */
    5971
    60 int main(int argc, char *argv[])
    61 {
    62         usb_dprintf_enable(NAME,1);
    63         futex_initialize(&usb_hub_list_lock, 0);
    64         usb_lst_init(&usb_hub_list);
    65         futex_up(&usb_hub_list_lock);
    66         fid_t fid = fibril_create(usb_hub_control_loop, NULL);
    67         if (fid == 0) {
    68                 dprintf(1, "failed to start fibril for HUB devices");
    69                 //printf("%s: failed to start fibril for HUB devices\n", NAME);
    70                 return ENOMEM;
    71         }
    72         fibril_add_ready(fid);
    73 
    74         return driver_main(&hub_driver);
    75 }
  • uspace/drv/usbhub/port_status.h

    r976f546 r19a1800  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
     28/** @addtogroup drvusbhub
     29 * @{
     30 */
    2831
    2932#ifndef PORT_STATUS_H
     
    3235#include <bool.h>
    3336#include <sys/types.h>
    34 #include <usb/devreq.h>
     37#include <usb/request.h>
    3538#include "usbhub_private.h"
    3639
     
    170173        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
    171174        request->request = USB_HUB_REQUEST_SET_FEATURE;
     175        request->value = USB_HUB_FEATURE_PORT_POWER;
     176        request->length = 0;
     177}
     178
     179/**
     180 * set the device request to be a port disable request
     181 * @param request
     182 * @param port
     183 */
     184static inline void usb_hub_unset_power_port_request(
     185usb_device_request_setup_packet_t * request, uint16_t port
     186){
     187        request->index = port;
     188        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     189        request->request = USB_HUB_REQUEST_CLEAR_FEATURE;
    172190        request->value = USB_HUB_FEATURE_PORT_POWER;
    173191        request->length = 0;
     
    302320#endif  /* PORT_STATUS_H */
    303321
     322/**
     323 * @}
     324 */
  • uspace/drv/usbhub/usbhub.c

    r976f546 r19a1800  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup usb hub driver
     28/** @addtogroup drvusbhub
    2929 * @{
    3030 */
     
    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>
     46#include <stdio.h>
    4447
    4548#include "usbhub.h"
    4649#include "usbhub_private.h"
    4750#include "port_status.h"
    48 
    49 static usb_iface_t hub_usb_iface = {
    50         .get_hc_handle = usb_drv_find_hc
     51#include "usb/usb.h"
     52#include "usb/pipes.h"
     53#include "usb/classes/classes.h"
     54
     55static ddf_dev_ops_t hub_device_ops = {
     56        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
    5157};
    5258
    53 static device_ops_t hub_device_ops = {
    54         .interfaces[USB_DEV_IFACE] = &hub_usb_iface
     59/** Hub status-change endpoint description
     60 *
     61 * For more see usb hub specification in 11.15.1 of
     62 */
     63static usb_endpoint_description_t status_change_endpoint_description = {
     64        .transfer_type = USB_TRANSFER_INTERRUPT,
     65        .direction = USB_DIRECTION_IN,
     66        .interface_class = USB_CLASS_HUB,
     67        .interface_subclass = 0,
     68        .interface_protocol = 0,
     69        .flags = 0
    5570};
     71
     72int usb_hub_control_loop(void * hub_info_param){
     73        usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
     74        while(true){
     75                usb_hub_check_hub_changes(hub_info);
     76                async_usleep(1000 * 1000 );/// \TODO proper number once
     77        }
     78        return 0;
     79}
     80
    5681
    5782//*********************************************
     
    6186//*********************************************
    6287
    63 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) {
     88/**
     89 * Initialize connnections to host controller, device, and device
     90 * control endpoint
     91 * @param hub
     92 * @param device
     93 * @return
     94 */
     95static int usb_hub_init_communication(usb_hub_info_t * hub){
     96        usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle);
     97        int opResult;
     98        opResult = usb_device_connection_initialize_from_device(
     99                        &hub->device_connection,
     100                        hub->device);
     101        if(opResult != EOK){
     102                dprintf(USB_LOG_LEVEL_ERROR,
     103                                "could not initialize connection to hc, errno %d",opResult);
     104                return opResult;
     105        }
     106        usb_log_debug("Initializing USB wire abstraction.\n");
     107        opResult = usb_hc_connection_initialize_from_device(&hub->connection,
     108                        hub->device);
     109        if(opResult != EOK){
     110                dprintf(USB_LOG_LEVEL_ERROR,
     111                                "could not initialize connection to device, errno %d",opResult);
     112                return opResult;
     113        }
     114        usb_log_debug("Initializing default control pipe.\n");
     115        opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
     116            &hub->device_connection);
     117        if(opResult != EOK){
     118                dprintf(USB_LOG_LEVEL_ERROR,
     119                                "could not initialize connection to device endpoint, errno %d",opResult);
     120        }
     121        return opResult;
     122}
     123
     124/**
     125 * When entering this function, hub->endpoints.control should be active.
     126 * @param hub
     127 * @return
     128 */
     129static int usb_hub_process_configuration_descriptors(
     130        usb_hub_info_t * hub){
     131        if(hub==NULL) {
     132                return EINVAL;
     133        }
     134        int opResult;
     135       
     136        //device descriptor
     137        usb_standard_device_descriptor_t std_descriptor;
     138        opResult = usb_request_get_device_descriptor(&hub->endpoints.control,
     139            &std_descriptor);
     140        if(opResult!=EOK){
     141                dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult);
     142                return opResult;
     143        }
     144        dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations",
     145                        std_descriptor.configuration_count);
     146        if(std_descriptor.configuration_count<1){
     147                dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE");
     148                //shouldn`t I return?
     149        }
     150
     151        //configuration descriptor
     152        /// \TODO check other configurations?
     153        usb_standard_configuration_descriptor_t config_descriptor;
     154        opResult = usb_request_get_bare_configuration_descriptor(
     155            &hub->endpoints.control, 0,
     156        &config_descriptor);
     157        if(opResult!=EOK){
     158                dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
     159                return opResult;
     160        }
     161        //set configuration
     162        opResult = usb_request_set_configuration(&hub->endpoints.control,
     163                config_descriptor.configuration_number);
     164
     165        if (opResult != EOK) {
     166                dprintf(USB_LOG_LEVEL_ERROR,
     167                                "something went wrong when setting hub`s configuration, %d",
     168                                opResult);
     169                return opResult;
     170        }
     171        dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",
     172                        config_descriptor.configuration_number);
     173
     174        //full configuration descriptor
     175        size_t transferred = 0;
     176        uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length);
     177        if (descriptors == NULL) {
     178                dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory");
     179                return ENOMEM;
     180        }
     181        opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control,
     182            0, descriptors,
     183            config_descriptor.total_length, &transferred);
     184        if(opResult!=EOK){
     185                free(descriptors);
     186                dprintf(USB_LOG_LEVEL_ERROR,
     187                                "could not get full configuration descriptor, %d",opResult);
     188                return opResult;
     189        }
     190        if (transferred != config_descriptor.total_length) {
     191                dprintf(USB_LOG_LEVEL_ERROR,
     192                                "received incorrect full configuration descriptor");
     193                return ELIMIT;
     194        }
     195
     196        usb_endpoint_mapping_t endpoint_mapping[1] = {
     197                {
     198                        .pipe = &hub->endpoints.status_change,
     199                        .description = &status_change_endpoint_description,
     200                        .interface_no =
     201                            usb_device_get_assigned_interface(hub->device)
     202                }
     203        };
     204        opResult = usb_endpoint_pipe_initialize_from_configuration(
     205            endpoint_mapping, 1,
     206            descriptors, config_descriptor.total_length,
     207            &hub->device_connection);
     208        if (opResult != EOK) {
     209                dprintf(USB_LOG_LEVEL_ERROR,
     210                                "Failed to initialize status change pipe: %s",
     211                    str_error(opResult));
     212                return opResult;
     213        }
     214        if (!endpoint_mapping[0].present) {
     215                dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \
     216                    "cannot understand what is happenning");
     217                return EREFUSED;
     218        }
     219
     220        free(descriptors);
     221        return EOK;
     222       
     223}
     224
     225
     226/**
     227 * Create hub representation from device information.
     228 * @param device
     229 * @return pointer to created structure or NULL in case of error
     230 */
     231usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
    64232        usb_hub_info_t* result = usb_new(usb_hub_info_t);
     233        result->device = device;
     234        int opResult;
     235        opResult = usb_hub_init_communication(result);
     236        if(opResult != EOK){
     237                free(result);
     238                return NULL;
     239        }
     240
    65241        //result->device = device;
    66242        result->port_count = -1;
    67         /// \TODO is this correct? is the device stored?
    68243        result->device = device;
    69244
    70 
    71         //printf("[usb_hub] phone to hc = %d\n", hc);
    72         if (hc < 0) {
    73                 return result;
    74         }
    75         //get some hub info
    76         usb_address_t addr = usb_drv_get_my_address(hc, device);
    77         dprintf(1,"[usb_hub] address of newly created hub = %d", addr);
    78         /*if(addr<0){
    79                 //return result;
    80 
    81         }*/
    82 
    83         result->usb_device = usb_new(usb_hcd_attached_device_info_t);
    84         result->usb_device->address = addr;
     245        //result->usb_device = usb_new(usb_hcd_attached_device_info_t);
     246        size_t received_size;
    85247
    86248        // get hub descriptor
    87         usb_target_t target;
    88         target.address = addr;
    89         target.endpoint = 0;
    90         usb_device_request_setup_packet_t request;
    91         //printf("[usb_hub] creating descriptor request\n");
    92         usb_hub_set_descriptor_request(&request);
    93 
    94         //printf("[usb_hub] creating serialized descriptor\n");
     249        dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton");
    95250        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    96251        usb_hub_descriptor_t * descriptor;
    97         size_t received_size;
    98         int opResult;
    99         //printf("[usb_hub] starting control transaction\n");
    100         opResult = usb_drv_sync_control_read(
    101                         hc, target, &request, serialized_descriptor,
     252        dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction");
     253        usb_endpoint_pipe_start_session(&result->endpoints.control);
     254        opResult = usb_request_get_descriptor(&result->endpoints.control,
     255                        USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     256                        USB_DESCTYPE_HUB,
     257                        0, 0, serialized_descriptor,
    102258                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    103         if (opResult != EOK) {
    104                 dprintf(1,"[usb_hub] failed when receiving hub descriptor, badcode = %d",opResult);
     259        usb_endpoint_pipe_end_session(&result->endpoints.control);
     260
     261        if (opResult != EOK) {
     262                dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult);
    105263                free(serialized_descriptor);
    106264                return result;
    107265        }
    108         //printf("[usb_hub] deserializing descriptor\n");
     266        dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor");
    109267        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    110268        if(descriptor==NULL){
    111                 dprintf(1,"[usb_hub] could not deserialize descriptor ");
     269                dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor ");
    112270                result->port_count = 1;///\TODO this code is only for debug!!!
    113271                return result;
    114272        }
    115         //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
     273
     274        dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
    116275        result->port_count = descriptor->ports_count;
    117         result->attached_devs = (usb_hub_attached_device_t*)
    118             malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t));
     276        result->attached_devs = (usb_hc_attached_device_t*)
     277            malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t));
    119278        int i;
    120279        for(i=0;i<result->port_count+1;++i){
    121                 result->attached_devs[i].devman_handle=0;
     280                result->attached_devs[i].handle=0;
    122281                result->attached_devs[i].address=0;
    123282        }
    124         //printf("[usb_hub] freeing data\n");
     283        dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data");
    125284        free(serialized_descriptor);
    126285        free(descriptor->devices_removable);
     
    129288        //finish
    130289
    131         dprintf(1,"[usb_hub] hub info created");
     290        dprintf(USB_LOG_LEVEL_INFO, "hub info created");
    132291
    133292        return result;
    134293}
    135294
    136 int usb_add_hub_device(device_t *dev) {
    137         dprintf(1, "add_hub_device(handle=%d)", (int) dev->handle);
    138         dprintf(1,"[usb_hub] hub device");
    139 
    140         /*
    141          * We are some (probably deeply nested) hub.
    142          * Thus, assign our own operations and explore already
    143          * connected devices.
    144          */
    145         dev->ops = &hub_device_ops;
    146 
    147         //create the hub structure
    148         //get hc connection
    149         int hc = usb_drv_hc_connect_auto(dev, 0);
    150         if (hc < 0) {
    151                 return hc;
    152         }
    153 
    154         usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc);
     295/**
     296 * Create hub representation and add it into hub list
     297 * @param dev
     298 * @return
     299 */
     300int usb_add_hub_device(ddf_dev_t *dev) {
     301        dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle);
     302
     303        //dev->ops = &hub_device_ops;
     304        (void) hub_device_ops;
     305
     306        usb_hub_info_t * hub_info = usb_create_hub_info(dev);
     307
     308        int opResult;
     309
     310        //perform final configurations
     311        usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
     312        // process descriptors
     313        opResult = usb_hub_process_configuration_descriptors(hub_info);
     314        if(opResult != EOK){
     315                dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d",
     316                                opResult);
     317                return opResult;
     318        }
     319        //power ports
     320        usb_device_request_setup_packet_t request;
    155321        int port;
    156         int opResult;
    157         usb_device_request_setup_packet_t request;
    158         usb_target_t target;
    159         target.address = hub_info->usb_device->address;
    160         target.endpoint = 0;
    161 
    162         //get configuration descriptor
    163         // this is not fully correct - there are more configurations
    164         // and all should be checked
    165         usb_standard_device_descriptor_t std_descriptor;
    166         opResult = usb_drv_req_get_device_descriptor(hc, target.address,
    167     &std_descriptor);
    168         if(opResult!=EOK){
    169                 dprintf(1,"[usb_hub] could not get device descriptor, %d",opResult);
    170                 return opResult;
    171         }
    172         dprintf(1,"[usb_hub] hub has %d configurations",std_descriptor.configuration_count);
    173         if(std_descriptor.configuration_count<1){
    174                 dprintf(1,"[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE");
    175         }
    176         /// \TODO check other configurations
    177         usb_standard_configuration_descriptor_t config_descriptor;
    178         opResult = usb_drv_req_get_bare_configuration_descriptor(hc,
    179         target.address, 0,
    180         &config_descriptor);
    181         if(opResult!=EOK){
    182                 dprintf(1,"[usb_hub] could not get configuration descriptor, %d",opResult);
    183                 return opResult;
    184         }
    185         //set configuration
    186         request.request_type = 0;
    187         request.request = USB_DEVREQ_SET_CONFIGURATION;
    188         request.index=0;
    189         request.length=0;
    190         request.value_high=0;
    191         request.value_low = config_descriptor.configuration_number;
    192         opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
    193         if (opResult != EOK) {
    194                 dprintf(1,"[usb_hub]something went wrong when setting hub`s configuration, %d", opResult);
    195         }
    196 
    197322        for (port = 1; port < hub_info->port_count+1; ++port) {
    198323                usb_hub_set_power_port_request(&request, port);
    199                 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
    200                 dprintf(1,"[usb_hub] powering port %d",port);
     324                opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control,
     325                                &request,sizeof(usb_device_request_setup_packet_t), NULL, 0);
     326                dprintf(USB_LOG_LEVEL_INFO, "powering port %d",port);
    201327                if (opResult != EOK) {
    202                         dprintf(1,"[usb_hub]something went wrong when setting hub`s %dth port", port);
     328                        dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port);
    203329                }
    204330        }
    205331        //ports powered, hub seems to be enabled
    206 
    207         ipc_hangup(hc);
     332        usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
    208333
    209334        //add the hub to list
    210         futex_down(&usb_hub_list_lock);
     335        //is this needed now?
     336        fibril_mutex_lock(&usb_hub_list_lock);
    211337        usb_lst_append(&usb_hub_list, hub_info);
    212         futex_up(&usb_hub_list_lock);
    213 
    214         dprintf(1,"[usb_hub] hub info added to list");
     338        fibril_mutex_unlock(&usb_hub_list_lock);
     339        dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list");
     340
     341        dprintf(USB_LOG_LEVEL_DEBUG, "adding to ddf");
     342        ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub");
     343        assert(hub_fun != NULL);
     344        hub_fun->ops = NULL;
     345
     346        int rc = ddf_fun_bind(hub_fun);
     347        assert(rc == EOK);
     348        rc = ddf_fun_add_to_class(hub_fun, "hub");
     349        assert(rc == EOK);
     350
     351        fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
     352        if (fid == 0) {
     353                dprintf(USB_LOG_LEVEL_ERROR,
     354                                ": failed to start monitoring fibril for new hub");
     355                return ENOMEM;
     356        }
     357        fibril_add_ready(fid);
     358
     359        dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created");
    215360        //(void)hub_info;
    216         usb_hub_check_hub_changes();
    217 
     361        //usb_hub_check_hub_changes();
    218362       
    219 
    220         dprintf(1,"[usb_hub] hub dev added");
    221         dprintf(1,"\taddress %d, has %d ports ",
    222                         hub_info->usb_device->address,
     363        dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
     364        //address is lost...
     365        dprintf(USB_LOG_LEVEL_DEBUG, "\taddress %d, has %d ports ",
     366                        //hub_info->endpoints.control.,
    223367                        hub_info->port_count);
    224         dprintf(1,"\tused configuration %d",config_descriptor.configuration_number);
    225368
    226369        return EOK;
    227370        //return ENOTSUP;
    228371}
    229 
    230372
    231373
     
    237379
    238380/**
    239  * convenience function for releasing default address and writing debug info
    240  * (these few lines are used too often to be written again and again)
    241  * @param hc
    242  * @return
    243  */
    244 inline static int usb_hub_release_default_address(int hc){
    245         int opResult;
    246         dprintf(1,"[usb_hub] releasing default address");
    247         opResult = usb_drv_release_default_address(hc);
    248         if (opResult != EOK) {
    249                 dprintf(1,"[usb_hub] failed to release default address");
    250         }
    251         return opResult;
    252 }
    253 
    254 /**
    255  * reset the port with new device and reserve the default address
     381 * Reset the port with new device and reserve the default address.
    256382 * @param hc
    257383 * @param port
    258384 * @param target
    259385 */
    260 static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
     386static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) {
    261387        usb_device_request_setup_packet_t request;
    262388        int opResult;
    263         dprintf(1,"[usb_hub] some connection changed");
     389        dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
     390        assert(hub->endpoints.control.hc_phone);
    264391        //get default address
    265         opResult = usb_drv_reserve_default_address(hc);
    266         if (opResult != EOK) {
    267                 dprintf(1,"[usb_hub] cannot assign default address, it is probably used");
     392        //opResult = usb_drv_reserve_default_address(hc);
     393        opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
     394       
     395        if (opResult != EOK) {
     396                dprintf(USB_LOG_LEVEL_WARNING,
     397                                "cannot assign default address, it is probably used %d",opResult);
    268398                return;
    269399        }
    270400        //reset port
    271401        usb_hub_set_reset_port_request(&request, port);
    272         opResult = usb_drv_sync_control_write(
    273                         hc, target,
    274                         &request,
     402        opResult = usb_endpoint_pipe_control_write(
     403                        &hub->endpoints.control,
     404                        &request,sizeof(usb_device_request_setup_packet_t),
    275405                        NULL, 0
    276406                        );
    277407        if (opResult != EOK) {
    278                 dprintf(1,"[usb_hub] something went wrong when reseting a port");
    279                 usb_hub_release_default_address(hc);
    280         }
    281 }
    282 
    283 /**
    284  * finalize adding new device after port reset
     408                dprintf(USB_LOG_LEVEL_ERROR,
     409                                "something went wrong when reseting a port %d",opResult);
     410                //usb_hub_release_default_address(hc);
     411                usb_hc_release_default_address(&hub->connection);
     412        }
     413}
     414
     415/**
     416 * Finalize adding new device after port reset
    285417 * @param hc
    286418 * @param port
     
    288420 */
    289421static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
    290                 int hc, uint16_t port, usb_target_t target) {
    291 
    292         int opResult;
    293         dprintf(1,"[usb_hub] finalizing add device");
    294         opResult = usb_hub_clear_port_feature(hc, target.address,
     422                uint16_t port, bool isLowSpeed) {
     423
     424        int opResult;
     425        dprintf(USB_LOG_LEVEL_INFO, "finalizing add device");
     426        opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
    295427            port, USB_HUB_FEATURE_C_PORT_RESET);
    296         if (opResult != EOK) {
    297                 dprintf(1,"[usb_hub] failed to clear port reset feature");
    298                 usb_hub_release_default_address(hc);
    299                 return;
    300         }
    301 
    302         /* Request address at from host controller. */
    303         usb_address_t new_device_address = usb_drv_request_address(hc);
     428
     429        if (opResult != EOK) {
     430                dprintf(USB_LOG_LEVEL_ERROR, "failed to clear port reset feature");
     431                usb_hc_release_default_address(&hub->connection);
     432                return;
     433        }
     434        //create connection to device
     435        usb_endpoint_pipe_t new_device_pipe;
     436        usb_device_connection_t new_device_connection;
     437        usb_device_connection_initialize_on_default_address(
     438                        &new_device_connection,
     439                        &hub->connection
     440                        );
     441        usb_endpoint_pipe_initialize_default_control(
     442                        &new_device_pipe,
     443                        &new_device_connection);
     444        /// \TODO get highspeed info
     445        usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
     446
     447
     448        /* Request address from host controller. */
     449        usb_address_t new_device_address = usb_hc_request_address(
     450                        &hub->connection,
     451                        speed/// \TODO fullspeed??
     452                        );
    304453        if (new_device_address < 0) {
    305                 dprintf(1,"[usb_hub] failed to get free USB address");
     454                dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address");
    306455                opResult = new_device_address;
    307                 usb_hub_release_default_address(hc);
    308                 return;
    309         }
    310         dprintf(1,"[usb_hub] setting new address");
    311         opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    312             new_device_address);
    313 
    314         if (opResult != EOK) {
    315                 dprintf(1,"[usb_hub] could not set address for new device");
    316                 usb_hub_release_default_address(hc);
    317                 return;
    318         }
    319 
    320 
    321         opResult = usb_hub_release_default_address(hc);
     456                usb_hc_release_default_address(&hub->connection);
     457                return;
     458        }
     459        dprintf(USB_LOG_LEVEL_INFO, "setting new address %d",new_device_address);
     460        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
     461        //    new_device_address);
     462        usb_endpoint_pipe_start_session(&new_device_pipe);
     463        opResult = usb_request_set_address(&new_device_pipe,new_device_address);
     464        usb_endpoint_pipe_end_session(&new_device_pipe);
     465        if (opResult != EOK) {
     466                dprintf(USB_LOG_LEVEL_ERROR,
     467                                "could not set address for new device %d",opResult);
     468                usb_hc_release_default_address(&hub->connection);
     469                return;
     470        }
     471
     472
     473        //opResult = usb_hub_release_default_address(hc);
     474        opResult = usb_hc_release_default_address(&hub->connection);
    322475        if(opResult!=EOK){
    323476                return;
     
    325478
    326479        devman_handle_t child_handle;
    327         opResult = usb_drv_register_child_in_devman(hc, hub->device,
    328             new_device_address, &child_handle);
    329         if (opResult != EOK) {
    330                 dprintf(1,"[usb_hub] could not start driver for new device");
    331                 return;
    332         }
    333         hub->attached_devs[port].devman_handle = child_handle;
     480        //??
     481    opResult = usb_device_register_child_in_devman(new_device_address,
     482            hub->connection.hc_handle, hub->device, &child_handle,
     483            NULL, NULL, NULL);
     484
     485        if (opResult != EOK) {
     486                dprintf(USB_LOG_LEVEL_ERROR,
     487                                "could not start driver for new device %d",opResult);
     488                return;
     489        }
     490        hub->attached_devs[port].handle = child_handle;
    334491        hub->attached_devs[port].address = new_device_address;
    335492
    336         opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
    337         if (opResult != EOK) {
    338                 dprintf(1,"[usb_hub] could not assign address of device in hcd");
    339                 return;
    340         }
    341         dprintf(1,"[usb_hub] new device address %d, handle %zu",
     493        //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
     494        opResult = usb_hc_register_device(
     495                        &hub->connection,
     496                        &hub->attached_devs[port]);
     497        if (opResult != EOK) {
     498                dprintf(USB_LOG_LEVEL_ERROR,
     499                                "could not assign address of device in hcd %d",opResult);
     500                return;
     501        }
     502        dprintf(USB_LOG_LEVEL_INFO, "new device address %d, handle %zu",
    342503            new_device_address, child_handle);
    343504
     
    345506
    346507/**
    347  * unregister device address in hc
     508 * Unregister device address in hc
    348509 * @param hc
    349510 * @param port
     
    351512 */
    352513static void usb_hub_removed_device(
    353     usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {
     514    usb_hub_info_t * hub,uint16_t port) {
    354515        //usb_device_request_setup_packet_t request;
    355516        int opResult;
    356517       
    357         /// \TODO remove device
    358 
    359         hub->attached_devs[port].devman_handle=0;
     518        /** \TODO remove device from device manager - not yet implemented in
     519         * devide manager
     520         */
     521       
    360522        //close address
    361523        if(hub->attached_devs[port].address!=0){
    362                 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     524                //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     525                opResult = usb_hc_unregister_device(
     526                                &hub->connection, hub->attached_devs[port].address);
    363527                if(opResult != EOK) {
    364                         dprintf(1,
    365                                         "[usb_hub] could not release address of removed device: %d"
    366                                         ,opResult);
     528                        dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
     529                            "removed device: %d", opResult);
    367530                }
    368531                hub->attached_devs[port].address = 0;
     532                hub->attached_devs[port].handle = 0;
    369533        }else{
    370                 dprintf(1,
    371                                 "[usb_hub] this is strange, disconnected device had no address");
     534                dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address");
    372535                //device was disconnected before it`s port was reset - return default address
    373                 usb_drv_release_default_address(hc);
    374         }
    375 }
    376 
    377 /**
    378  * process interrupts on given hub port
     536                //usb_drv_release_default_address(hc);
     537                usb_hc_release_default_address(&hub->connection);
     538        }
     539}
     540
     541
     542/**
     543 *Process over current condition on port.
     544 *
     545 * Turn off the power on the port.
     546 *
     547 * @param hub
     548 * @param port
     549 */
     550static void usb_hub_over_current( usb_hub_info_t * hub,
     551                uint16_t port){
     552        int opResult;
     553        opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
     554            port, USB_HUB_FEATURE_PORT_POWER);
     555        if(opResult!=EOK){
     556                dprintf(USB_LOG_LEVEL_ERROR, "cannot power off port %d;  %d",
     557                                port, opResult);
     558        }
     559}
     560
     561/**
     562 * Process interrupts on given hub port
    379563 * @param hc
    380564 * @param port
    381565 * @param target
    382566 */
    383 static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,
    384         uint16_t port, usb_address_t address) {
    385         dprintf(1,"[usb_hub] interrupt at port %d", port);
     567static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     568        uint16_t port) {
     569        dprintf(USB_LOG_LEVEL_DEBUG, "interrupt at port %d", port);
    386570        //determine type of change
    387         usb_target_t target;
    388         target.address=address;
    389         target.endpoint=0;
     571        usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
     572       
     573        int opResult;
     574
    390575        usb_port_status_t status;
    391576        size_t rcvd_size;
    392577        usb_device_request_setup_packet_t request;
    393         int opResult;
     578        //int opResult;
    394579        usb_hub_set_port_status_request(&request, port);
    395580        //endpoint 0
    396581
    397         opResult = usb_drv_sync_control_read(
    398                         hc, target,
    399                         &request,
     582        opResult = usb_endpoint_pipe_control_read(
     583                        pipe,
     584                        &request, sizeof(usb_device_request_setup_packet_t),
    400585                        &status, 4, &rcvd_size
    401586                        );
    402587        if (opResult != EOK) {
    403                 dprintf(1,"[usb_hub] ERROR: could not get port status");
     588                dprintf(USB_LOG_LEVEL_ERROR, "could not get port status");
    404589                return;
    405590        }
    406591        if (rcvd_size != sizeof (usb_port_status_t)) {
    407                 dprintf(1,"[usb_hub] ERROR: received status has incorrect size");
     592                dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size");
    408593                return;
    409594        }
    410595        //something connected/disconnected
    411596        if (usb_port_connect_change(&status)) {
    412                 opResult = usb_hub_clear_port_feature(hc, target.address,
     597                opResult = usb_hub_clear_port_feature(pipe,
    413598                    port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    414599                // TODO: check opResult
    415600                if (usb_port_dev_connected(&status)) {
    416                         dprintf(1,"[usb_hub] some connection changed");
    417                         usb_hub_init_add_device(hc, port, target);
     601                        dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
     602                        usb_hub_init_add_device(hub, port);
    418603                } else {
    419                         usb_hub_removed_device(hub, hc, port, target);
     604                        usb_hub_removed_device(hub, port);
     605                }
     606        }
     607        //over current
     608        if (usb_port_overcurrent_change(&status)) {
     609                //check if it was not auto-resolved
     610                if(usb_port_over_current(&status)){
     611                        usb_hub_over_current(hub,port);
     612                }else{
     613                        dprintf(USB_LOG_LEVEL_INFO,
     614                                "over current condition was auto-resolved on port %d",port);
    420615                }
    421616        }
    422617        //port reset
    423618        if (usb_port_reset_completed(&status)) {
    424                 dprintf(1,"[usb_hub] port reset complete");
     619                dprintf(USB_LOG_LEVEL_INFO, "port reset complete");
    425620                if (usb_port_enabled(&status)) {
    426                         usb_hub_finalize_add_device(hub, hc, port, target);
     621                        usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status));
    427622                } else {
    428                         dprintf(1,"[usb_hub] ERROR: port reset, but port still not enabled");
     623                        dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled");
    429624                }
    430625        }
     
    434629        usb_port_set_reset_completed(&status, false);
    435630        usb_port_set_dev_connected(&status, false);
    436         if (status) {
    437                 dprintf(1,"[usb_hub]there was some unsupported change on port %d",port);
     631        if (status>>16) {
     632                dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status);
     633
    438634        }
    439635        /// \TODO handle other changes
    440         /// \TODO debug log for various situations
    441 
    442 }
    443 
    444 /* Check changes on all known hubs.
    445  */
    446 void usb_hub_check_hub_changes(void) {
     636}
     637
     638/**
     639 * Check changes on particular hub
     640 * @param hub_info_param
     641 */
     642void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
     643        int opResult;
     644        opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
     645        if(opResult != EOK){
     646                dprintf(USB_LOG_LEVEL_ERROR,
     647                                "could not initialize communication for hub; %d", opResult);
     648                return;
     649        }
     650
     651        size_t port_count = hub_info->port_count;
     652
     653        /// FIXME: count properly
     654        size_t byte_length = ((port_count+1) / 8) + 1;
     655                void *change_bitmap = malloc(byte_length);
     656        size_t actual_size;
     657
    447658        /*
    448          * Iterate through all hubs.
     659         * Send the request.
    449660         */
    450         usb_general_list_t * lst_item;
    451         futex_down(&usb_hub_list_lock);
    452         for (lst_item = usb_hub_list.next;
    453                         lst_item != &usb_hub_list;
    454                         lst_item = lst_item->next) {
    455                 futex_up(&usb_hub_list_lock);
    456                 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
    457                 /*
    458                  * Check status change pipe of this hub.
    459                  */
    460 
    461                 usb_target_t target;
    462                 target.address = hub_info->usb_device->address;
    463                 target.endpoint = 1;/// \TODO get from endpoint descriptor
    464                 dprintf(1,"[usb_hub] checking changes for hub at addr %d",
    465                     target.address);
    466 
    467                 size_t port_count = hub_info->port_count;
    468 
    469                 /*
    470                  * Connect to respective HC.
    471                  */
    472                 int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
    473                 if (hc < 0) {
    474                         continue;
     661        opResult = usb_endpoint_pipe_read(
     662                        &hub_info->endpoints.status_change,
     663                        change_bitmap, byte_length, &actual_size
     664                        );
     665
     666        if (opResult != EOK) {
     667                free(change_bitmap);
     668                dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
     669                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     670                return;
     671        }
     672        unsigned int port;
     673        opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
     674        if(opResult!=EOK){
     675                dprintf(USB_LOG_LEVEL_ERROR, "could not start control pipe session %d",
     676                                opResult);
     677                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     678                return;
     679        }
     680        opResult = usb_hc_connection_open(&hub_info->connection);
     681        if(opResult!=EOK){
     682                dprintf(USB_LOG_LEVEL_ERROR, "could not start host controller session %d",
     683                                opResult);
     684                usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
     685                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     686                return;
     687        }
     688
     689        ///todo, opresult check, pre obe konekce
     690        for (port = 1; port < port_count+1; ++port) {
     691                bool interrupt =
     692                                (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
     693                if (interrupt) {
     694                        usb_hub_process_interrupt(
     695                                hub_info, port);
    475696                }
    476 
    477                 /// FIXME: count properly
    478                 size_t byte_length = ((port_count+1) / 8) + 1;
    479 
    480                 void *change_bitmap = malloc(byte_length);
    481                 size_t actual_size;
    482                 usb_handle_t handle;
    483 
    484                 /*
    485                  * Send the request.
    486                  */
    487                 int opResult = usb_drv_async_interrupt_in(hc, target,
    488                                 change_bitmap, byte_length, &actual_size,
    489                                 &handle);
    490 
    491                 usb_drv_async_wait_for(handle);
    492 
    493                 if (opResult != EOK) {
    494                         dprintf(1,"[usb_hub] something went wrong while getting status of hub");
    495                         continue;
    496                 }
    497                 unsigned int port;
    498                 for (port = 1; port < port_count+1; ++port) {
    499                         bool interrupt =
    500                                         (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
    501                         if (interrupt) {
    502                                 usb_hub_process_interrupt(
    503                                         hub_info, hc, port, hub_info->usb_device->address);
    504                         }
    505                 }
    506                 free(change_bitmap);
    507 
    508                 ipc_hangup(hc);
    509                 futex_down(&usb_hub_list_lock);
    510         }
    511         futex_up(&usb_hub_list_lock);
    512 }
    513 
    514 
     697        }
     698        usb_hc_connection_close(&hub_info->connection);
     699        usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
     700        usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     701        free(change_bitmap);
     702}
    515703
    516704
  • uspace/drv/usbhub/usbhub.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbhub
    3030 * @{
    3131 */
     
    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
    6175/**
    6276 * function running the hub-controlling loop.
    63  * @param noparam fundtion does not need any parameters
     77 * @param hub_info_param hub info pointer
    6478 */
    65 int usb_hub_control_loop(void * noparam);
     79int usb_hub_control_loop(void * hub_info_param);
    6680
    6781/** Callback when new hub device is detected.
     
    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/**
    75  * check changes on all registered hubs
     89 * check changes on specified hub
     90 * @param hub_info_param pointer to usb_hub_info_t structure
    7691 */
    77 void usb_hub_check_hub_changes(void);
     92void usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
    7893
    7994
    80 //int usb_add_hub_device(device_t *);
    8195
    8296
  • uspace/drv/usbhub/usbhub_private.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbhub
    3030 * @{
    3131 */
    3232/** @file
    33  * @brief Hub driver.
     33 * @brief Hub driver private definitions
    3434 */
    3535
     
    4242#include <adt/list.h>
    4343#include <bool.h>
    44 #include <driver.h>
    45 #include <futex.h>
     44#include <ddf/driver.h>
     45#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/**
    70  * create hub structure instance
     70 * Create hub structure instance
    7171 *
    7272 * Set the address and port count information most importantly.
     
    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
    80 /** list of hubs maanged by this driver */
     80/** List of hubs maanged by this driver */
    8181extern usb_general_list_t usb_hub_list;
    8282
    83 /** lock for hub list*/
    84 extern futex_t usb_hub_list_lock;
     83/** Lock for hub list*/
     84extern fibril_mutex_t usb_hub_list_lock;
    8585
    8686
    8787/**
    88  * perform complete control read transaction
     88 * Perform complete control read transaction
    8989 *
    90  * manages all three steps of transaction: setup, read and finalize
     90 * Manages all three steps of transaction: setup, read and finalize
    9191 * @param phone
    9292 * @param target
    93  * @param request request for data
    94  * @param rcvd_buffer received data
     93 * @param request Request packet
     94 * @param rcvd_buffer Received data
    9595 * @param rcvd_size
    96  * @param actual_size actual size of received data
     96 * @param actual_size Actual size of received data
    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/**
    106  * perform complete control write transaction
     107 * Perform complete control write transaction
    107108 *
    108  * manages all three steps of transaction: setup, write and finalize
     109 * Manages all three steps of transaction: setup, write and finalize
    109110 * @param phone
    110111 * @param target
    111  * @param request request to send data
     112 * @param request Request packet to send data
    112113 * @param sent_buffer
    113114 * @param sent_size
    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/**
    123  * set the device request to be a get hub descriptor request.
     124 * Set the device request to be a get hub descriptor request.
    124125 * @warning the size is allways set to USB_HUB_MAX_DESCRIPTOR_SIZE
    125126 * @param request
     
    137138}
    138139
    139 static inline int usb_hub_clear_port_feature(int hc, usb_address_t address,
     140/**
     141 * Clear feature on hub port.
     142 *
     143 * @param hc Host controller telephone
     144 * @param address Hub address
     145 * @param port_index Port
     146 * @param feature Feature selector
     147 * @return Operation result
     148 */
     149static inline int usb_hub_clear_port_feature(usb_endpoint_pipe_t *pipe,
    140150    int port_index,
    141151    usb_hub_class_feature_t feature) {
    142         usb_target_t target = {
    143                 .address = address,
    144                 .endpoint = 0
    145         };
     152       
    146153        usb_device_request_setup_packet_t clear_request = {
    147154                .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
     
    151158        };
    152159        clear_request.value = feature;
    153         return usb_drv_psync_control_write(hc, target, &clear_request,
     160        return usb_endpoint_pipe_control_write(pipe, &clear_request,
    154161            sizeof(clear_request), NULL, 0);
    155162}
    156163
     164/**
     165 * @brief create uint8_t array with serialized descriptor
     166 *
     167 * @param descriptor
     168 * @return newly created serializd descriptor pointer
     169 */
     170void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor);
     171
     172/**
     173 * @brief create deserialized desriptor structure out of serialized descriptor
     174 *
     175 * The serialized descriptor must be proper usb hub descriptor,
     176 * otherwise an eerror might occur.
     177 *
     178 * @param sdescriptor serialized descriptor
     179 * @return newly created deserialized descriptor pointer
     180 */
     181usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * sdescriptor);
    157182
    158183
  • uspace/drv/usbhub/usblist.c

    r976f546 r19a1800  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup usb hub driver
     28/** @addtogroup drvusbhub
    2929 * @{
    3030 */
  • uspace/drv/usbhub/usblist.h

    r976f546 r19a1800  
    2727 */
    2828
    29 
    30 #ifndef USBLIST_H
    31 #define USBLIST_H
    32 /** @addtogroup usb hub driver
     29/** @addtogroup drvusbhub
    3330 * @{
    3431 */
     
    4037 * much simpler and more straight-forward semantics.
    4138 */
     39#ifndef USBLIST_H
     40#define USBLIST_H
    4241
    4342/**
     
    7877}
    7978
    80 
     79#endif  /* USBLIST_H */
    8180/**
    8281 * @}
    8382 */
    84 
    85 
    86 
    87 #endif  /* USBLIST_H */
    88 
  • uspace/drv/usbhub/utils.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup libusb usb
     29/** @addtogroup drvusbhub
    3030 * @{
    3131 */
     
    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

    r976f546 r19a1800  
    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         transfers.c
     38        usbmid.c
    3739
    3840include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/vhc/Makefile

    r976f546 r19a1800  
    4444        conndev.c \
    4545        connhost.c \
    46         debug.c \
    4746        devices.c \
    4847        hc.c \
  • uspace/drv/vhc/conn.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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 *);
     53void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     54void on_client_close(ddf_fun_t *);
    5355
    5456
  • uspace/drv/vhc/conndev.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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{
     
    8888                int callback = IPC_GET_ARG5(*icall);
    8989                virtdev_connection_t *dev
    90                     = virtdev_add_device(callback);
     90                    = 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];
    9999                int rc = get_device_name(callback, devname, DEVICE_NAME_MAXLENGTH);
    100100
    101                 dprintf(0, "virtual device connected (name: %s)",
    102                     rc == EOK ? devname : "<unknown>");
    103 
    104                 /* FIXME: destroy the device when the client disconnects. */
     101                usb_log_info("New virtual device `%s' (id = %x).\n",
     102                    rc == EOK ? devname : "<unknown>", dev->id);
    105103
    106104                return;
    107105        }
    108106
    109         ipc_answer_0(icallid, EINVAL);
     107        async_answer_0(icallid, EINVAL);
     108}
     109
     110/** Callback for DDF when client disconnects.
     111 *
     112 * @param d Device the client was connected to.
     113 */
     114void on_client_close(ddf_fun_t *fun)
     115{
     116        /*
     117         * Maybe a virtual device is being unplugged.
     118         */
     119        virtdev_connection_t *dev = virtdev_find((sysarg_t)fibril_get_id());
     120        if (dev == NULL) {
     121                return;
     122        }
     123
     124        usb_log_info("Virtual device disconnected (id = %x).\n", dev->id);
     125        virtdev_destroy_device(dev);
    110126}
    111127
  • uspace/drv/vhc/connhost.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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"
    4142#include "conn.h"
    4243#include "hc.h"
     44
    4345
    4446typedef struct {
     
    4648        usbhc_iface_transfer_out_callback_t out_callback;
    4749        usbhc_iface_transfer_in_callback_t in_callback;
    48         device_t *dev;
     50        ddf_fun_t *fun;
     51        size_t reported_size;
    4952        void *arg;
    5053} transfer_info_t;
    5154
     55typedef struct {
     56        usb_direction_t direction;
     57        usb_target_t target;
     58        usbhc_iface_transfer_out_callback_t out_callback;
     59        usbhc_iface_transfer_in_callback_t in_callback;
     60        ddf_fun_t *fun;
     61        void *arg;
     62        void *data_buffer;
     63        size_t data_buffer_size;
     64} control_transfer_info_t;
     65
    5266static void universal_callback(void *buffer, size_t size,
    53     usb_transaction_outcome_t outcome, void *arg)
     67    int outcome, void *arg)
    5468{
    5569        transfer_info_t *transfer = (transfer_info_t *) arg;
     70
     71        if (transfer->reported_size != (size_t) -1) {
     72                size = transfer->reported_size;
     73        }
    5674
    5775        switch (transfer->direction) {
    5876                case USB_DIRECTION_IN:
    59                         transfer->in_callback(transfer->dev,
     77                        transfer->in_callback(transfer->fun,
    6078                            outcome, size,
    6179                            transfer->arg);
    6280                        break;
    6381                case USB_DIRECTION_OUT:
    64                         transfer->out_callback(transfer->dev,
     82                        transfer->out_callback(transfer->fun,
    6583                            outcome,
    6684                            transfer->arg);
     
    7492}
    7593
    76 static transfer_info_t *create_transfer_info(device_t *dev,
     94static transfer_info_t *create_transfer_info(ddf_fun_t *fun,
    7795    usb_direction_t direction, void *arg)
    7896{
     
    83101        transfer->out_callback = NULL;
    84102        transfer->arg = arg;
    85         transfer->dev = dev;
     103        transfer->fun = fun;
     104        transfer->reported_size = (size_t) -1;
    86105
    87106        return transfer;
    88107}
    89108
    90 static int enqueue_transfer_out(device_t *dev,
     109static void control_abort_prematurely(control_transfer_info_t *transfer,
     110    size_t size, int outcome)
     111{
     112        switch (transfer->direction) {
     113                case USB_DIRECTION_IN:
     114                        transfer->in_callback(transfer->fun,
     115                            outcome, size,
     116                            transfer->arg);
     117                        break;
     118                case USB_DIRECTION_OUT:
     119                        transfer->out_callback(transfer->fun,
     120                            outcome,
     121                            transfer->arg);
     122                        break;
     123                default:
     124                        assert(false && "unreachable");
     125                        break;
     126        }
     127}
     128
     129static void control_callback_two(void *buffer, size_t size,
     130    int outcome, void *arg)
     131{
     132        control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg;
     133
     134        if (outcome != EOK) {
     135                control_abort_prematurely(ctrl_transfer, outcome, size);
     136                free(ctrl_transfer);
     137                return;
     138        }
     139
     140        transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->fun,
     141            ctrl_transfer->direction, ctrl_transfer->arg);
     142        transfer->out_callback = ctrl_transfer->out_callback;
     143        transfer->in_callback = ctrl_transfer->in_callback;
     144        transfer->reported_size = size;
     145
     146        switch (ctrl_transfer->direction) {
     147                case USB_DIRECTION_IN:
     148                        hc_add_transaction_to_device(false, ctrl_transfer->target,
     149                            USB_TRANSFER_CONTROL,
     150                            NULL, 0,
     151                            universal_callback, transfer);
     152                        break;
     153                case USB_DIRECTION_OUT:
     154                        hc_add_transaction_from_device(ctrl_transfer->target,
     155                            USB_TRANSFER_CONTROL,
     156                            NULL, 0,
     157                            universal_callback, transfer);
     158                        break;
     159                default:
     160                        assert(false && "unreachable");
     161                        break;
     162        }
     163
     164        free(ctrl_transfer);
     165}
     166
     167static void control_callback_one(void *buffer, size_t size,
     168    int outcome, void *arg)
     169{
     170        control_transfer_info_t *transfer = (control_transfer_info_t *) arg;
     171
     172        if (outcome != EOK) {
     173                control_abort_prematurely(transfer, outcome, size);
     174                free(transfer);
     175                return;
     176        }
     177
     178        switch (transfer->direction) {
     179                case USB_DIRECTION_IN:
     180                        hc_add_transaction_from_device(transfer->target,
     181                            USB_TRANSFER_CONTROL,
     182                            transfer->data_buffer, transfer->data_buffer_size,
     183                            control_callback_two, transfer);
     184                        break;
     185                case USB_DIRECTION_OUT:
     186                        hc_add_transaction_to_device(false, transfer->target,
     187                            USB_TRANSFER_CONTROL,
     188                            transfer->data_buffer, transfer->data_buffer_size,
     189                            control_callback_two, transfer);
     190                        break;
     191                default:
     192                        assert(false && "unreachable");
     193                        break;
     194        }
     195}
     196
     197static control_transfer_info_t *create_control_transfer_info(ddf_fun_t *fun,
     198    usb_direction_t direction, usb_target_t target,
     199    void *data_buffer, size_t data_buffer_size,
     200    void *arg)
     201{
     202        control_transfer_info_t *transfer
     203            = malloc(sizeof(control_transfer_info_t));
     204
     205        transfer->direction = direction;
     206        transfer->target = target;
     207        transfer->in_callback = NULL;
     208        transfer->out_callback = NULL;
     209        transfer->arg = arg;
     210        transfer->fun = fun;
     211        transfer->data_buffer = data_buffer;
     212        transfer->data_buffer_size = data_buffer_size;
     213
     214        return transfer;
     215}
     216
     217static int enqueue_transfer_out(ddf_fun_t *fun,
    91218    usb_target_t target, usb_transfer_type_t transfer_type,
    92219    void *buffer, size_t size,
    93220    usbhc_iface_transfer_out_callback_t callback, void *arg)
    94221{
    95         dprintf(3, "transfer OUT [%d.%d (%s); %zu]",
     222        usb_log_debug2("Transfer OUT [%d.%d (%s); %zu].\n",
    96223            target.address, target.endpoint,
    97224            usb_str_transfer_type(transfer_type),
     
    99226
    100227        transfer_info_t *transfer
    101             = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
     228            = create_transfer_info(fun, USB_DIRECTION_OUT, arg);
    102229        transfer->out_callback = callback;
    103230
     
    108235}
    109236
    110 static int enqueue_transfer_setup(device_t *dev,
     237static int enqueue_transfer_in(ddf_fun_t *fun,
    111238    usb_target_t target, usb_transfer_type_t transfer_type,
    112239    void *buffer, size_t size,
    113     usbhc_iface_transfer_out_callback_t callback, void *arg)
    114 {
    115         dprintf(3, "transfer SETUP [%d.%d (%s); %zu]",
     240    usbhc_iface_transfer_in_callback_t callback, void *arg)
     241{
     242        usb_log_debug2("Transfer IN [%d.%d (%s); %zu].\n",
    116243            target.address, target.endpoint,
    117244            usb_str_transfer_type(transfer_type),
     
    119246
    120247        transfer_info_t *transfer
    121             = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
    122         transfer->out_callback = callback;
    123 
    124         hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
    125             universal_callback, transfer);
    126 
    127         return EOK;
    128 }
    129 
    130 static int enqueue_transfer_in(device_t *dev,
    131     usb_target_t target, usb_transfer_type_t transfer_type,
    132     void *buffer, size_t size,
    133     usbhc_iface_transfer_in_callback_t callback, void *arg)
    134 {
    135         dprintf(3, "transfer IN [%d.%d (%s); %zu]",
    136             target.address, target.endpoint,
    137             usb_str_transfer_type(transfer_type),
    138             size);
    139 
    140         transfer_info_t *transfer
    141             = create_transfer_info(dev, USB_DIRECTION_IN, arg);
     248            = create_transfer_info(fun, USB_DIRECTION_IN, arg);
    142249        transfer->in_callback = callback;
    143250
     
    149256
    150257
    151 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,
    152260    void *data, size_t size,
    153261    usbhc_iface_transfer_out_callback_t callback, void *arg)
    154262{
    155         return enqueue_transfer_out(dev, target, USB_TRANSFER_INTERRUPT,
     263        return enqueue_transfer_out(fun, target, USB_TRANSFER_INTERRUPT,
    156264            data, size,
    157265            callback, arg);
    158266}
    159267
    160 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,
    161270    void *data, size_t size,
    162271    usbhc_iface_transfer_in_callback_t callback, void *arg)
    163272{
    164         return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
     273        return enqueue_transfer_in(fun, target, USB_TRANSFER_INTERRUPT,
    165274            data, size,
    166275            callback, arg);
    167276}
    168277
    169 static int control_write_setup(device_t *dev, usb_target_t target,
    170     void *data, size_t size,
     278static int control_write(ddf_fun_t *fun, usb_target_t target,
     279    size_t max_packet_size,
     280    void *setup_packet, size_t setup_packet_size,
     281    void *data, size_t data_size,
    171282    usbhc_iface_transfer_out_callback_t callback, void *arg)
    172283{
    173         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    174             data, size,
    175             callback, arg);
    176 }
    177 
    178 static int control_write_data(device_t *dev, usb_target_t target,
    179     void *data, size_t size,
    180     usbhc_iface_transfer_out_callback_t callback, void *arg)
    181 {
    182         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    183             data, size,
    184             callback, arg);
    185 }
    186 
    187 static int control_write_status(device_t *dev, usb_target_t target,
     284        control_transfer_info_t *transfer
     285            = create_control_transfer_info(fun, USB_DIRECTION_OUT, target,
     286            data, data_size, arg);
     287        transfer->out_callback = callback;
     288
     289        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     290            setup_packet, setup_packet_size,
     291            control_callback_one, transfer);
     292
     293        return EOK;
     294}
     295
     296static int control_read(ddf_fun_t *fun, usb_target_t target,
     297    size_t max_packet_size,
     298    void *setup_packet, size_t setup_packet_size,
     299    void *data, size_t data_size,
    188300    usbhc_iface_transfer_in_callback_t callback, void *arg)
    189301{
    190         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    191             NULL, 0,
    192             callback, arg);
    193 }
    194 
    195 static int control_read_setup(device_t *dev, usb_target_t target,
    196     void *data, size_t size,
    197     usbhc_iface_transfer_out_callback_t callback, void *arg)
    198 {
    199         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    200             data, size,
    201             callback, arg);
    202 }
    203 
    204 static int control_read_data(device_t *dev, usb_target_t target,
    205     void *data, size_t size,
    206     usbhc_iface_transfer_in_callback_t callback, void *arg)
    207 {
    208         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    209             data, size,
    210             callback, arg);
    211 }
    212 
    213 static int control_read_status(device_t *dev, usb_target_t target,
    214     usbhc_iface_transfer_out_callback_t callback, void *arg)
    215 {
    216         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    217             NULL, 0,
    218             callback, arg);
     302        control_transfer_info_t *transfer
     303            = create_control_transfer_info(fun, USB_DIRECTION_IN, target,
     304            data, data_size, arg);
     305        transfer->in_callback = callback;
     306
     307        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     308            setup_packet, setup_packet_size,
     309            control_callback_one, transfer);
     310
     311        return EOK;
    219312}
    220313
    221314static usb_address_keeping_t addresses;
    222315
    223 
    224 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)
    225331{
    226332        usb_address_keeping_reserve_default(&addresses);
     
    228334}
    229335
    230 static int release_default_address(device_t *dev)
     336static int release_default_address(ddf_fun_t *fun)
    231337{
    232338        usb_address_keeping_release_default(&addresses);
     
    234340}
    235341
    236 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)
    237344{
    238345        usb_address_t addr = usb_address_keeping_request(&addresses);
     
    245352}
    246353
    247 static int release_address(device_t *dev, usb_address_t address)
     354static int release_address(ddf_fun_t *fun, usb_address_t address)
    248355{
    249356        return usb_address_keeping_release(&addresses, address);
    250357}
    251358
    252 static int bind_address(device_t *dev, usb_address_t address,
     359static int bind_address(ddf_fun_t *fun, usb_address_t address,
    253360    devman_handle_t handle)
    254361{
     
    257364}
    258365
    259 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,
    260380    usb_address_t *address)
    261381{
    262         usb_address_t addr = usb_address_keeping_find(&addresses, handle);
    263         if (addr < 0) {
    264                 return addr;
    265         }
    266 
    267         *address = addr;
    268         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);
    269386}
    270387
     
    275392
    276393usbhc_iface_t vhc_iface = {
    277         .tell_address = tell_address,
    278 
    279394        .reserve_default_address = reserve_default_address,
    280395        .release_default_address = release_default_address,
     
    286401        .interrupt_in = interrupt_in,
    287402
    288         .control_write_setup = control_write_setup,
    289         .control_write_data = control_write_data,
    290         .control_write_status = control_write_status,
    291 
    292         .control_read_setup = control_read_setup,
    293         .control_read_data = control_read_data,
    294         .control_read_status = control_read_status
     403        .control_write = control_write,
     404        .control_read = control_read
    295405};
     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
    296417
    297418/**
  • uspace/drv/vhc/devices.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    3434 */
    3535
    36 #include <ipc/ipc.h>
    3736#include <adt/list.h>
    3837#include <bool.h>
     
    5857/** Create virtual device.
    5958 *
    60  * @param address USB address.
    6159 * @param phone Callback phone.
     60 * @param id Device id.
    6261 * @return New device.
    63  * @retval NULL Out of memory or address already occupied.
    64  */
    65 virtdev_connection_t *virtdev_add_device(int phone)
     62 * @retval NULL Out of memory.
     63 */
     64virtdev_connection_t *virtdev_add_device(int phone, sysarg_t id)
    6665{
    6766        virtdev_connection_t *dev = (virtdev_connection_t *)
    6867            malloc(sizeof(virtdev_connection_t));
     68        if (dev == NULL) {
     69                return NULL;
     70        }
     71
    6972        dev->phone = phone;
     73        dev->id = id;
    7074        list_append(&dev->link, &devices);
    7175       
     
    7377       
    7478        return dev;
     79}
     80
     81/** Find virtual device by id.
     82 *
     83 * @param id Device id.
     84 * @return Device with given id.
     85 * @retval NULL No such device.
     86 */
     87virtdev_connection_t *virtdev_find(sysarg_t id)
     88{
     89        link_t *pos;
     90        list_foreach(pos, &devices) {
     91                virtdev_connection_t *dev
     92                    = list_get_instance(pos, virtdev_connection_t, link);
     93                if (dev->id == id) {
     94                        return dev;
     95                }
     96        }
     97
     98        return NULL;
    7599}
    76100
     
    88112 * @param transaction Transaction to be sent over the bus.
    89113 */
    90 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *transaction)
    91 {
     114int virtdev_send_to_all(transaction_t *transaction)
     115{
     116        /* For easier debugging. */
     117        switch (transaction->type) {
     118                case USBVIRT_TRANSACTION_SETUP:
     119                case USBVIRT_TRANSACTION_OUT:
     120                        transaction->actual_len = transaction->len;
     121                        break;
     122                case USBVIRT_TRANSACTION_IN:
     123                        transaction->actual_len = 0;
     124                        break;
     125                default:
     126                        assert(false && "unreachable branch in switch()");
     127        }
     128        int outcome = EBADCHECKSUM;
     129
    92130        link_t *pos;
    93131        list_foreach(pos, &devices) {
     
    138176                } else {
    139177                        async_wait_for(req, &answer_rc);
     178                        transaction->actual_len = IPC_GET_ARG1(answer_data);
    140179                        rc = (int)answer_rc;
     180                }
     181
     182                /*
     183                 * If at least one device was able to accept this
     184                 * transaction and process it, we can announce success.
     185                 */
     186                if (rc == EOK) {
     187                        outcome = EOK;
    141188                }
    142189        }
     
    148195        if (virtual_hub_device.address == transaction->target.address) {
    149196                size_t tmp;
    150                 dprintf(1, "sending `%s' transaction to hub",
     197                usb_log_debug2("Sending `%s' transaction to hub.\n",
    151198                    usbvirt_str_transaction_type(transaction->type));
    152199                switch (transaction->type) {
     
    164211                                    transaction->buffer, transaction->len,
    165212                                    &tmp);
    166                                 if (tmp < transaction->len) {
    167                                         transaction->len = tmp;
    168                                 }
     213                                transaction->actual_len = tmp;
    169214                                break;
    170215                               
     
    176221                                break;
    177222                }
    178                 dprintf(4, "transaction on hub processed...");
     223                outcome = EOK;
    179224        }
    180225       
     
    183228         * real-life image.
    184229         */
    185         return USB_OUTCOME_OK;
     230        return outcome;
    186231}
    187232
  • uspace/drv/vhc/devices.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    4545        /** Phone used when sending data to device. */
    4646        int phone;
     47        /** Unique identification. */
     48        sysarg_t id;
    4749        /** Linked-list handle. */
    4850        link_t link;
    4951} virtdev_connection_t;
    5052
    51 virtdev_connection_t *virtdev_add_device(int);
    52 virtdev_connection_t *virtdev_get_mine(void);
     53virtdev_connection_t *virtdev_add_device(int, sysarg_t);
     54virtdev_connection_t *virtdev_find(sysarg_t);
    5355void virtdev_destroy_device(virtdev_connection_t *);
    54 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *);
     56int virtdev_send_to_all(transaction_t *);
    5557
    5658#endif
  • uspace/drv/vhc/hc.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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)
    93 {
    94         dprintf(3, "transaction " TRANSACTION_FORMAT " done, outcome: %s",
     91    int outcome)
     92{
     93        usb_log_debug2("Transaction " TRANSACTION_FORMAT " done: %s.\n",
    9594            TRANSACTION_PRINTF(*transaction),
    96             usb_str_transaction_outcome(outcome));
    97        
    98         transaction->callback(transaction->buffer, transaction->len, outcome,
    99             transaction->callback_arg);
     95            str_error(outcome));
     96       
     97        transaction->callback(transaction->buffer, transaction->actual_len,
     98            outcome, transaction->callback_arg);
    10099}
    101100
     
    108107        static unsigned int seed = 4573;
    109108       
    110         printf("%s: transaction processor ready.\n", NAME);
     109        usb_log_info("Transaction processor ready.\n");
    111110       
    112111        while (true) {
     
    125124                list_remove(first_transaction_link);
    126125               
    127 
    128                 dprintf(0, "about to process " TRANSACTION_FORMAT " [%s]",
     126                usb_log_debug("Processing " TRANSACTION_FORMAT " [%s].\n",
    129127                    TRANSACTION_PRINTF(*transaction), ports);
    130128
    131                 dprintf(3, "processing transaction " TRANSACTION_FORMAT "",
    132                     TRANSACTION_PRINTF(*transaction));
    133                
    134                 usb_transaction_outcome_t outcome;
     129                int outcome;
    135130                outcome = virtdev_send_to_all(transaction);
    136131               
     
    148143        fid_t fid = fibril_create(hc_manager_fibril, NULL);
    149144        if (fid == 0) {
    150                 printf(NAME ": failed to start HC manager fibril\n");
     145                usb_log_fatal("Failed to start HC manager fibril.\n");
    151146                return;
    152147        }
     
    169164        transaction->buffer = buffer;
    170165        transaction->len = len;
     166        transaction->actual_len = len;
    171167        transaction->callback = callback;
    172168        transaction->callback_arg = arg;
    173        
    174         dprintf(3, "creating transaction " TRANSACTION_FORMAT,
     169
     170        return transaction;
     171}
     172
     173static void hc_add_transaction(transaction_t *transaction)
     174{
     175        usb_log_debug("Adding transaction " TRANSACTION_FORMAT ".\n",
    175176            TRANSACTION_PRINTF(*transaction));
    176        
    177         return transaction;
     177        list_append(&transaction->link, &transaction_list);
    178178}
    179179
     
    189189            target, transfer_type,
    190190            buffer, len, callback, arg);
    191         list_append(&transaction->link, &transaction_list);
     191        hc_add_transaction(transaction);
    192192}
    193193
     
    202202            target, transfer_type,
    203203            buffer, len, callback, arg);
    204         list_append(&transaction->link, &transaction_list);
     204        hc_add_transaction(transaction);
    205205}
    206206
  • uspace/drv/vhc/hc.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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. */
     
    6565        /** Transaction data length. */
    6666        size_t len;
     67        /** Data length actually transfered. */
     68        size_t actual_len;
    6769        /** Callback after transaction is done. */
    6870        hc_transaction_done_callback_t callback;
  • uspace/drv/vhc/hcd.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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,
     58        .close = on_client_close,
    7159        .default_handler = default_connection_handler
    7260};
    7361
    74 static int vhc_count = 0;
    75 static int vhc_add_device(device_t *dev)
     62static int vhc_add_device(ddf_dev_t *dev)
    7663{
     64        static int vhc_count = 0;
     65        int rc;
     66
    7767        /*
    7868         * Currently, we know how to simulate only single HC.
     
    8272        }
    8373
    84         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        }
    8583
    86         dev->ops = &vhc_ops;
     84        hc->ops = &vhc_ops;
    8785
    88         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");
    8994
    9095        /*
    9196         * Initialize our hub and announce its presence.
    9297         */
    93         virtual_hub_device_init(dev);
     98        virtual_hub_device_init(hc);
    9499
    95         printf("%s: virtual USB host controller ready.\n", NAME);
     100        usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
     101            (size_t) dev->handle, (size_t) hc->handle);
    96102
    97103        return EOK;
     
    114120         * in devman output.
    115121         */
    116         sleep(5);
     122        //sleep(5);
    117123
    118         usb_dprintf_enable(NAME, 0);
     124        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    119125
    120126        printf(NAME ": virtual USB host controller driver.\n");
     
    133139         * We are also a driver within devman framework.
    134140         */
    135         return driver_main(&vhc_driver);
     141        return ddf_driver_main(&vhc_driver);
    136142}
    137143
  • uspace/drv/vhc/hub.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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);
     
    6369            = fibril_create(hub_register_in_devman_fibril, hc_dev);
    6470        if (root_hub_registration == 0) {
    65                 printf(NAME ": failed to register root hub\n");
     71                usb_log_fatal("Failed to create hub registration fibril.\n");
    6672                return;
    6773        }
    6874
    6975        fibril_add_ready(root_hub_registration);
     76}
     77
     78static int pretend_port_rest(int unused, void *unused2)
     79{
     80        return EOK;
    7081}
    7182
     
    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 = usb_drv_hc_connect(hc_dev, hc_dev->handle, IPC_FLAG_BLOCKING);
    82         if (hc < 0) {
    83                 printf(NAME ": failed to register root hub\n");
    84                 return hc;
     92        /*
     93         * Wait until parent device is properly initialized.
     94         */
     95        int phone;
     96        do {
     97                phone = devman_device_connect(hc_dev->handle, 0);
     98        } while (phone < 0);
     99        async_hangup(phone);
     100
     101        int rc;
     102
     103        usb_hc_connection_t hc_conn;
     104        rc = usb_hc_connection_initialize(&hc_conn, hc_dev->handle);
     105        assert(rc == EOK);
     106
     107        rc = usb_hc_connection_open(&hc_conn);
     108        assert(rc == EOK);
     109
     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));
    85118        }
    86119
    87         usb_drv_reserve_default_address(hc);
     120        usb_hc_connection_close(&hc_conn);
    88121
    89         usb_address_t hub_address = usb_drv_request_address(hc);
    90         usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, hub_address);
     122        usb_log_info("Created root hub function (handle %zu).\n",
     123            (size_t) hub_dev->handle);
    91124
    92         usb_drv_release_default_address(hc);
    93 
    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);
    97 
    98         return EOK;
     125        return 0;
    99126}
    100127       
  • uspace/drv/vhc/hub.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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"
     
    155155}
    156156
     157/** Disconnects a device from a hub.
     158 *
     159 * @param hub Hub the device was connected to.
     160 * @param device Device to be disconnected.
     161 * @return Error code.
     162 */
     163int hub_disconnect_device(hub_t *hub, void *device)
     164{
     165        size_t index = hub_find_device(hub, device);
     166        if (index == (size_t) -1) {
     167                return ENOENT;
     168        }
     169
     170        hub_port_t *port = &hub->ports[index];
     171
     172        port->connected_device = NULL;
     173        port->state = HUB_PORT_STATE_DISCONNECTED;
     174        set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
     175
     176        return EOK;
     177}
     178
    157179/** Find port device is connected to.
    158180 *
     
    173195        }
    174196
    175         return 0;
     197        return -1;
    176198}
    177199
  • uspace/drv/vhc/hub/hub.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    3838#include <fibril_synch.h>
    3939
     40#ifndef HUB_PORT_COUNT
    4041#define HUB_PORT_COUNT 2
     42#endif
    4143#define BITS2BYTES(bits) (bits ? ((((bits)-1)>>3)+1) : 0)
    4244
     
    9496void hub_init(hub_t *);
    9597size_t hub_connect_device(hub_t *, void *);
     98int hub_disconnect_device(hub_t *, void *);
    9699size_t hub_find_device(hub_t *, void *);
    97100void hub_acquire(hub_t *);
  • uspace/drv/vhc/hub/virthub.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    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"
     
    164164        dev->device_data = hub;
    165165
    166         usbvirt_connect_local(dev);
    167 
    168         return EOK;
     166        int rc;
     167#ifdef STANDALONE_HUB
     168        dev->name = "hub";
     169        rc = usbvirt_connect(dev);
     170#else
     171        rc = usbvirt_connect_local(dev);
     172#endif
     173
     174        return rc;
    169175}
    170176
     
    203209
    204210        hub_acquire(hub);
    205         /* TODO: implement. */
     211        hub_disconnect_device(hub, conn);
    206212        hub_release(hub);
    207213
  • uspace/drv/vhc/hub/virthub.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    3737
    3838#include <usbvirt/device.h>
     39#include "hub.h"
     40
     41#ifdef STANDALONE_HUB
     42#define virtdev_connection_t int
     43#else
    3944#include "../devices.h"
    40 #include "hub.h"
     45#endif
    4146
    4247/** Endpoint number for status change pipe. */
  • uspace/drv/vhc/hub/virthubops.c

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
  • uspace/drv/vhc/vhcd.h

    r976f546 r19a1800  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    4545#define DEVMAP_PATH_DEV NAMESPACE "/" NAME_DEV
    4646
    47 #define dprintf(level, format, ...) \
    48         usb_dprintf(NAME, (level), format "\n", ##__VA_ARGS__)
    49 void dprintf_inval_call(int, ipc_call_t, sysarg_t);
     47//#define dprintf(level, format, ...)
     48//      usb_dprintf(NAME, (level), format "\n", ##__VA_ARGS__)
     49//void dprintf_inval_call(int, ipc_call_t, sysarg_t);
    5050
    5151#endif
Note: See TracChangeset for help on using the changeset viewer.