Changeset a8ac368 in mainline for uspace


Ignore:
Timestamp:
2011-03-29T20:08:53Z (14 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fc883bb
Parents:
0d92638 (diff), 51e5608 (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:

development changes

Location:
uspace
Files:
4 added
1 deleted
55 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/cat/cat.c

    r0d92638 ra8ac368  
    11/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
     2 * Copyright (c) 2011, Martin Sucha
    23 * All rights reserved.
    34 *
     
    3536#include <str.h>
    3637#include <fcntl.h>
     38#include <io/console.h>
     39#include <io/color.h>
     40#include <io/style.h>
     41#include <io/keycode.h>
     42#include <errno.h>
     43#include <vfs/vfs.h>
     44#include <assert.h>
    3745
    3846#include "config.h"
     
    4856
    4957static const char *cat_oops = "That option is not yet supported\n";
     58static const char *hexchars = "0123456789abcdef";
     59
     60static bool paging_enabled = false;
     61static size_t chars_remaining = 0;
     62static size_t lines_remaining = 0;
     63static sysarg_t console_cols = 0;
     64static sysarg_t console_rows = 0;
     65static bool should_quit = false;
    5066
    5167static struct option const long_options[] = {
     
    5672        { "buffer", required_argument, 0, 'b' },
    5773        { "more", no_argument, 0, 'm' },
     74        { "hex", no_argument, 0, 'x' },
    5875        { 0, 0, 0, 0 }
    5976};
     
    7592                "  -b, --buffer ##  Set the read buffer size to ##\n"
    7693                "  -m, --more       Pause after each screen full\n"
     94                "  -x, --hex        Print bytes as hex values\n"
    7795                "Currently, %s is under development, some options don't work.\n",
    7896                cmdname, cmdname);
     
    82100}
    83101
    84 static unsigned int cat_file(const char *fname, size_t blen)
     102static void waitprompt()
     103{
     104        console_set_pos(fphone(stdout), 0, console_rows-1);
     105        console_set_color(fphone(stdout), COLOR_BLUE, COLOR_WHITE, 0);
     106        printf("ENTER/SPACE/PAGE DOWN - next page, "
     107               "ESC/Q - quit, C - continue unpaged");
     108        fflush(stdout);
     109        console_set_style(fphone(stdout), STYLE_NORMAL);
     110}
     111
     112static void waitkey()
     113{
     114        console_event_t ev;
     115       
     116        while (true) {
     117                if (!console_get_event(fphone(stdin), &ev)) {
     118                        return;
     119                }
     120                if (ev.type == KEY_PRESS) {
     121                        if (ev.key == KC_ESCAPE || ev.key == KC_Q) {
     122                                should_quit = true;
     123                                return;
     124                        }
     125                        if (ev.key == KC_C) {
     126                                paging_enabled = false;
     127                                return;
     128                        }
     129                        if (ev.key == KC_ENTER || ev.key == KC_SPACE ||
     130                            ev.key == KC_PAGE_DOWN) {
     131                                return;
     132                        }
     133                }
     134        }
     135        assert(false);
     136}
     137
     138static void newpage()
     139{
     140        console_clear(fphone(stdout));
     141        chars_remaining = console_cols;
     142        lines_remaining = console_rows-1;
     143}
     144
     145static void paged_char(wchar_t c)
     146{
     147        putchar(c);
     148        if (paging_enabled) {
     149                chars_remaining--;
     150                if (c == '\n' || chars_remaining == 0) {
     151                        chars_remaining = console_cols;
     152                        lines_remaining--;
     153                }
     154                if (lines_remaining == 0) {
     155                        fflush(stdout);
     156                        waitprompt();
     157                        waitkey();
     158                        newpage();
     159                }
     160        }
     161}
     162
     163static unsigned int cat_file(const char *fname, size_t blen, bool hex)
    85164{
    86165        int fd, bytes = 0, count = 0, reads = 0;
    87166        off64_t total = 0;
    88167        char *buff = NULL;
     168        int i;
     169        size_t offset = 0;
    89170
    90171        fd = open(fname, O_RDONLY);
     
    109190                        count += bytes;
    110191                        buff[bytes] = '\0';
    111                         printf("%s", buff);
     192                        offset = 0;
     193                        for (i = 0; i < bytes && !should_quit; i++) {
     194                                if (hex) {
     195                                        paged_char(hexchars[((uint8_t)buff[i])/16]);
     196                                        paged_char(hexchars[((uint8_t)buff[i])%16]);
     197                                }
     198                                else {
     199                                        wchar_t c = str_decode(buff, &offset, bytes);
     200                                        if (c == 0) {
     201                                                // reached end of string
     202                                                break;
     203                                        }
     204                                        paged_char(c);
     205                                }
     206                               
     207                        }
    112208                        reads++;
    113209                }
    114         } while (bytes > 0);
     210        } while (bytes > 0 && !should_quit);
    115211
    116212        close(fd);
     
    131227        unsigned int argc, i, ret = 0, buffer = 0;
    132228        int c, opt_ind;
     229        bool hex = false;
     230        bool more = false;
     231        sysarg_t rows, cols;
     232        int rc;
     233       
     234        // reset global state
     235        // TODO: move to structure?
     236        paging_enabled = false;
     237        chars_remaining = 0;
     238        lines_remaining = 0;
     239        console_cols = 0;
     240        console_rows = 0;
     241        should_quit = false;
    133242
    134243        argc = cli_count_args(argv);
    135244
    136245        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    137                 c = getopt_long(argc, argv, "hvmH:t:b:", long_options, &opt_ind);
     246                c = getopt_long(argc, argv, "xhvmH:t:b:", long_options, &opt_ind);
    138247                switch (c) {
    139248                case 'h':
     
    153262                        break;
    154263                case 'm':
    155                         printf("%s", cat_oops);
    156                         return CMD_FAILURE;
     264                        more = true;
     265                        break;
     266                case 'x':
     267                        hex = true;
     268                        break;
    157269                }
    158270        }
     
    168280        if (buffer <= 0)
    169281                buffer = CAT_DEFAULT_BUFLEN;
    170 
    171         for (i = optind; argv[i] != NULL; i++)
    172                 ret += cat_file(argv[i], buffer);
     282       
     283        if (more) {
     284                rc = console_get_size(fphone(stdout), &cols, &rows);
     285                if (rc != EOK) {
     286                        printf("%s - cannot get console size\n", cmdname);
     287                        return CMD_FAILURE;
     288                }
     289                console_cols = cols;
     290                console_rows = rows;
     291                paging_enabled = true;
     292                newpage();
     293        }
     294
     295        for (i = optind; argv[i] != NULL && !should_quit; i++)
     296                ret += cat_file(argv[i], buffer, hex);
    173297
    174298        if (ret)
  • uspace/app/bdsh/cmds/modules/cat/cat.h

    r0d92638 ra8ac368  
    44/* Prototypes for the cat command, excluding entry points */
    55
    6 static unsigned int cat_file(const char *, size_t);
     6static unsigned int cat_file(const char *, size_t, bool);
    77
    88#endif /* CAT_H */
  • uspace/app/bdsh/cmds/modules/cp/cp.c

    r0d92638 ra8ac368  
    108108        for (;;) {
    109109                ssize_t res;
     110                size_t written = 0;
    110111
    111112                bytes = read(fd1, buff, blen);
     
    120121                         * returned less data than requested.
    121122                         */
    122                         bytes = write(fd2, buff, res);
     123                        bytes = write(fd2, buff + written, res);
    123124                        if (bytes < 0)
    124125                                goto err;
     126                        written += bytes;
    125127                        res -= bytes;
    126128                } while (res > 0);
  • uspace/app/bdsh/cmds/modules/rm/rm.c

    r0d92638 ra8ac368  
    101101}
    102102
     103static unsigned int rm_recursive_not_empty_dirs(const char *path)
     104{
     105        DIR *dirp;
     106        struct dirent *dp;
     107        char buff[PATH_MAX];
     108        unsigned int scope;
     109        unsigned int ret = 0;
     110
     111        dirp = opendir(path);
     112        if (!dirp) {
     113                /* May have been deleted between scoping it and opening it */
     114                cli_error(CL_EFAIL, "Could not open %s", path);
     115                return ret;
     116        }
     117
     118        memset(buff, 0, sizeof(buff));
     119        while ((dp = readdir(dirp))) {
     120                snprintf(buff, PATH_MAX - 1, "%s/%s", path, dp->d_name);
     121                scope = rm_scope(buff);
     122                switch (scope) {
     123                case RM_BOGUS:
     124                        break;
     125                case RM_FILE:
     126                        ret += rm_single(buff);
     127                        break;
     128                case RM_DIR:
     129                        ret += rm_recursive(buff);
     130                        break;
     131                }
     132        }
     133       
     134        return ret;
     135}
     136
    103137static unsigned int rm_recursive(const char *path)
    104138{
    105139        int rc;
     140        unsigned int ret = 0;
    106141
    107142        /* First see if it will just go away */
     
    111146
    112147        /* Its not empty, recursively scan it */
    113         cli_error(CL_ENOTSUP,
    114                 "Can not remove %s, directory not empty", path);
    115         return 1;
     148        ret = rm_recursive_not_empty_dirs(path);
     149
     150        /* Delete directory */
     151        rc = rmdir(path);
     152        if (rc == 0)
     153                return ret;
     154
     155        cli_error(CL_ENOTSUP, "Can not remove %s", path);
     156
     157        return ret + 1;
    116158}
    117159
  • uspace/app/init/init.c

    r0d92638 ra8ac368  
    313313        getterm("term/vc5", "/app/bdsh", false);
    314314        getterm("term/vc6", "/app/klog", false);
     315
     316#ifdef CONFIG_DEVMAN_EARLY_LAUNCH
     317        spawn("/srv/devman");
     318#else
    315319        getterm("term/vc7", "/srv/devman", false);
    316        
     320#endif
     321
    317322        return 0;
    318323}
  • uspace/app/klog/klog.c

    r0d92638 ra8ac368  
    4444#include <io/klog.h>
    4545#include <sysinfo.h>
     46#include <fibril_synch.h>
    4647
    4748#define NAME       "klog"
     
    5455static FILE *log;
    5556
     57/* Serialize the output a bit. This will not avoid messed-up log completely
     58   but chances for are pretty high (experimentally confirmed). */
     59static FIBRIL_MUTEX_INITIALIZE(log_mutex);
     60
    5661static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    5762{
     63        fibril_mutex_lock(&log_mutex);
     64       
    5865        size_t klog_start = (size_t) IPC_GET_ARG1(*call);
    5966        size_t klog_len = (size_t) IPC_GET_ARG2(*call);
     
    7481                fsync(fileno(log));
    7582        }
     83       
     84        fibril_mutex_unlock(&log_mutex);
    7685}
    7786
  • uspace/app/usbinfo/info.c

    r0d92638 ra8ac368  
    294294}
    295295
     296
     297void dump_status(usbinfo_device_t *dev)
     298{
     299        int rc;
     300        uint16_t device_status = 0;
     301        uint16_t ctrl_pipe_status = 0;
     302
     303        /* Device status first. */
     304        rc = usb_request_get_status(&dev->ctrl_pipe,
     305            USB_REQUEST_RECIPIENT_DEVICE, 0,
     306            &device_status);
     307        if (rc != EOK) {
     308                printf("%sFailed to get device status: %s.\n",
     309                    get_indent(0), str_error(rc));
     310                goto try_ctrl_pipe_status;
     311        }
     312
     313        printf("%sDevice status 0x%04x: power=%s, remote-wakeup=%s.\n",
     314            get_indent(0),
     315            device_status,
     316            device_status & USB_DEVICE_STATUS_SELF_POWERED ? "self" : "bus",
     317            device_status & USB_DEVICE_STATUS_REMOTE_WAKEUP ? "yes" : "no");
     318
     319        /* Interface is not interesting, skipping ;-). */
     320
     321        /* Control endpoint zero. */
     322try_ctrl_pipe_status:
     323        rc = usb_request_get_status(&dev->ctrl_pipe,
     324            USB_REQUEST_RECIPIENT_ENDPOINT, 0,
     325            &ctrl_pipe_status);
     326        if (rc != EOK) {
     327                printf("%sFailed to get control endpoint status: %s.\n",
     328                    get_indent(0), str_error(rc));
     329                goto leave;
     330        }
     331
     332        printf("%sControl endpoint zero status %04X: halted=%s.\n",
     333            get_indent(0),
     334            ctrl_pipe_status,
     335            ctrl_pipe_status & USB_ENDPOINT_STATUS_HALTED ? "yes" : "no");
     336
     337leave:
     338        return;
     339}
     340
    296341/** @}
    297342 */
  • uspace/app/usbinfo/main.c

    r0d92638 ra8ac368  
    136136        _OPTION("-T --descriptor-tree-full", "Print detailed descriptor tree");
    137137        _OPTION("-s --strings", "Try to print all string descriptors.");
     138        _OPTION("-S --status", "Get status of the device.");
    138139
    139140        printf("\n");
     
    152153        {"descriptor-tree-full", no_argument, NULL, 'T'},
    153154        {"strings", no_argument, NULL, 's'},
     155        {"status", no_argument, NULL, 'S'},
    154156        {0, 0, NULL, 0}
    155157};
    156 static const char *short_options = "himtTs";
     158static const char *short_options = "himtTsS";
    157159
    158160static usbinfo_action_t actions[] = {
     
    180182                .opt = 's',
    181183                .action = dump_strings,
     184                .active = false
     185        },
     186        {
     187                .opt = 'S',
     188                .action = dump_status,
    182189                .active = false
    183190        },
  • uspace/app/usbinfo/usbinfo.h

    r0d92638 ra8ac368  
    8484void dump_descriptor_tree_full(usbinfo_device_t *);
    8585void dump_strings(usbinfo_device_t *);
     86void dump_status(usbinfo_device_t *);
    8687
    8788
  • uspace/drv/ohci/Makefile

    r0d92638 ra8ac368  
    3737        main.c \
    3838        hc.c \
     39        ohci.c \
    3940        root_hub.c \
    4041        pci.c
  • uspace/drv/ohci/batch.c

    r0d92638 ra8ac368  
    118118        instance->next_step = batch_call_in_and_dispose;
    119119        /* TODO: implement */
    120         usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     120        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    121121}
    122122/*----------------------------------------------------------------------------*/
  • uspace/drv/ohci/hc.c

    r0d92638 ra8ac368  
    3939#include <usb/debug.h>
    4040#include <usb/usb.h>
    41 #include <usb/hub.h>
    4241#include <usb/ddfiface.h>
    4342#include <usb/usbdevice.h>
     
    4544#include "hc.h"
    4645
    47 static int dummy_reset(int foo, void *arg);
    4846static int interrupt_emulator(hc_t *instance);
     47/*----------------------------------------------------------------------------*/
     48int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
     49{
     50        assert(instance);
     51        assert(hub_fun);
     52
     53        usb_address_t hub_address =
     54            device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);
     55        instance->rh.address = hub_address;
     56        usb_device_keeper_bind(
     57            &instance->manager, hub_address, hub_fun->handle);
     58
     59        char *match_str = NULL;
     60        int ret = asprintf(&match_str, "usb&mid");
     61        ret = (match_str == NULL) ? ret : EOK;
     62        if (ret < 0) {
     63                usb_log_error("Failed to create root hub match-id string.\n");
     64                return ret;
     65        }
     66
     67        ret = ddf_fun_add_match_id(hub_fun, match_str, 100);
     68        if (ret != EOK) {
     69                usb_log_error("Failed add create root hub match-id.\n");
     70        }
     71        return ret;
     72}
    4973/*----------------------------------------------------------------------------*/
    5074int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
     
    6892        }
    6993
     94        rh_init(&instance->rh, dev, instance->registers);
    7095
    71         rh_init(&instance->rh, dev, instance->registers);
    7296        /* TODO: implement */
    73         return EOK;
    74 }
    75 /*----------------------------------------------------------------------------*/
    76 int hc_register_hub(hc_t *instance)
    77 {
    78         async_usleep(1000000);
    79 #define CHECK_RET_RETURN(ret, msg...) \
    80         if (ret != EOK) { \
    81                 usb_log_error(msg); \
    82                 return ret; \
    83         } else (void)0
    84         assert(instance);
    85         assert(instance->ddf_instance);
    86         assert(instance->ddf_instance->handle);
    87         ddf_dev_t *dev = instance->rh.device;
    88         int ret = EOK;
    89 
    90         usb_hc_connection_t conn;
    91         ret =
    92             usb_hc_connection_initialize(&conn, instance->ddf_instance->handle);
    93         CHECK_RET_RETURN(ret, "Failed to initialize hc connection.\n");
    94 
    95         ret = usb_hc_connection_open(&conn);
    96         CHECK_RET_RETURN(ret, "Failed to open hc connection.\n");
    97 
    98         usb_address_t address;
    99         devman_handle_t handle;
    100         ret = usb_hc_new_device_wrapper(dev, &conn, USB_SPEED_FULL, dummy_reset,
    101             0, instance, &address, &handle, NULL, NULL, NULL);
    102         if (ret != EOK) {
    103                 usb_log_error("Failed to add rh device.\n");
    104                 instance->rh.address = -1;
    105                 return ret;
    106         }
    107 
    108         ret = usb_hc_connection_close(&conn);
    109         CHECK_RET_RETURN(ret, "Failed to close hc connection.\n");
    11097        return EOK;
    11198}
     
    134121}
    135122/*----------------------------------------------------------------------------*/
    136 static int dummy_reset(int foo, void *arg)
    137 {
    138         hc_t *hc = (hc_t*)arg;
    139         assert(hc);
    140         hc->rh.address = 0;
    141         return EOK;
    142 }
    143 /*----------------------------------------------------------------------------*/
    144 static int interrupt_emulator(hc_t *instance)
     123int interrupt_emulator(hc_t *instance)
    145124{
    146125        assert(instance);
  • uspace/drv/ohci/hc.h

    r0d92638 ra8ac368  
    5757} hc_t;
    5858
     59int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
     60
    5961int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
    6062     uintptr_t regs, size_t reg_size, bool interrupts);
    61 
    62 int hc_register_hub(hc_t *instance);
    6363
    6464int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
  • uspace/drv/ohci/iface.h

    r0d92638 ra8ac368  
    3333 * Common OHCI definitions.
    3434 */
    35 #ifndef DRV_OHCI_OHCI_H
    36 #define DRV_OHCI_OHCI_H
     35#ifndef DRV_OHCI_IFACE_H
     36#define DRV_OHCI_IFACE_H
    3737
    3838#include <usbhc_iface.h>
    39 
    40 #define NAME "ohci"
    4139
    4240extern usbhc_iface_t hc_iface;
  • uspace/drv/ohci/main.c

    r0d92638 ra8ac368  
    3434 */
    3535#include <ddf/driver.h>
    36 #include <ddf/interrupt.h>
    37 #include <device/hw_res.h>
    3836#include <errno.h>
    3937#include <str_error.h>
    4038
    41 #include <usb_iface.h>
    42 #include <usb/ddfiface.h>
    4339#include <usb/debug.h>
    4440
    45 #include "pci.h"
    46 #include "iface.h"
    47 #include "hc.h"
     41#include "ohci.h"
     42
     43#define NAME "ohci"
    4844
    4945static int ohci_add_device(ddf_dev_t *device);
    50 static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
    51 {
    52         assert(handle);
    53   assert(fun != NULL);
    54 
    55   *handle = fun->handle;
    56   return EOK;
    57 }
    58 /*----------------------------------------------------------------------------*/
    59 static int get_address(
    60     ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
    61 {
    62         assert(fun);
    63         usb_device_keeper_t *manager = &fun_to_hc(fun)->manager;
    64   usb_address_t addr = usb_device_keeper_find(manager, handle);
    65   if (addr < 0) {
    66     return addr;
    67   }
    68 
    69   if (address != NULL) {
    70     *address = addr;
    71   }
    72 
    73   return EOK;
    74 }
    75 /*----------------------------------------------------------------------------*/
    76 /** IRQ handling callback, identifies device
    77  *
    78  * @param[in] dev DDF instance of the device to use.
    79  * @param[in] iid (Unused).
    80  * @param[in] call Pointer to the call that represents interrupt.
    81  */
    82 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    83 {
    84         assert(dev);
    85         hc_t *hc = (hc_t*)dev->driver_data;
    86         assert(hc);
    87         hc_interrupt(hc, 0);
    88 }
    8946/*----------------------------------------------------------------------------*/
    9047static driver_ops_t ohci_driver_ops = {
     
    9754};
    9855/*----------------------------------------------------------------------------*/
    99 static usb_iface_t hc_usb_iface = {
    100         .get_address = get_address,
    101         .get_hc_handle = get_hc_handle,
    102 };
    103 /*----------------------------------------------------------------------------*/
    104 static ddf_dev_ops_t hc_ops = {
    105         .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    106         .interfaces[USBHC_DEV_IFACE] = &hc_iface,
    107 };
    108 /*----------------------------------------------------------------------------*/
    10956/** Initializes a new ddf driver instance of OHCI hcd.
    11057 *
     
    11259 * @return Error code.
    11360 */
    114 static int ohci_add_device(ddf_dev_t *device)
     61int ohci_add_device(ddf_dev_t *device)
    11562{
     63        usb_log_debug("ohci_add_device() called\n");
    11664        assert(device);
    117 #define CHECK_RET_RETURN(ret, message...) \
    118 if (ret != EOK) { \
    119         usb_log_error(message); \
    120         return ret; \
    121 }
    122 
    123         uintptr_t mem_reg_base = 0;
    124         size_t mem_reg_size = 0;
    125         int irq = 0;
    126 
    127         int ret =
    128             pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
    129         CHECK_RET_RETURN(ret,
    130             "Failed(%d) to get memory addresses:.\n", ret, device->handle);
    131         usb_log_info("Memory mapped regs at 0x%X (size %zu), IRQ %d.\n",
    132             mem_reg_base, mem_reg_size, irq);
    133 
    134         ret = pci_disable_legacy(device);
    135         CHECK_RET_RETURN(ret,
    136             "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
    137 
    138         hc_t *hcd = malloc(sizeof(hc_t));
    139         if (hcd == NULL) {
     65        ohci_t *ohci = malloc(sizeof(ohci_t));
     66        if (ohci == NULL) {
    14067                usb_log_error("Failed to allocate OHCI driver.\n");
    14168                return ENOMEM;
    14269        }
    14370
    144         ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
    145         if (hc_fun == NULL) {
    146                 usb_log_error("Failed to create OHCI function.\n");
    147                 free(hcd);
    148                 return ENOMEM;
    149         }
    150 
    151         bool interrupts = false;
    152         ret = pci_enable_interrupts(device);
     71        int ret = ohci_init(ohci, device);
    15372        if (ret != EOK) {
    154                 usb_log_warning(
    155                     "Failed(%d) to enable interrupts, fall back to polling.\n",
    156                     ret);
    157         } else {
    158                 usb_log_debug("Hw interrupts enabled.\n");
    159                 interrupts = true;
    160         }
    161 
    162         ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts);
    163         if (ret != EOK) {
    164                 usb_log_error("Failed to initialize OHCI driver.\n");
    165                 free(hcd);
     73                usb_log_error("Failed to initialize OHCI driver: %s.\n",
     74                    str_error(ret));
    16675                return ret;
    16776        }
     77        device->driver_data = ohci;
    16878
    169         ret = register_interrupt_handler(device, irq, irq_handler, NULL);
    170 
    171         hc_fun->ops = &hc_ops;
    172         ret = ddf_fun_bind(hc_fun);
    173         if (ret != EOK) {
    174                 usb_log_error("Failed to bind OHCI function.\n");
    175                 ddf_fun_destroy(hc_fun);
    176                 free(hcd);
    177                 return ret;
    178         }
    179         hc_fun->driver_data = hcd;
    180 
    181         fid_t later = fibril_create((int(*)(void*))hc_register_hub, hcd);
    182         fibril_add_ready(later);
    183 
    184         usb_log_info("Controlling new OHCI device `%s' (handle %llu).\n",
    185             device->name, device->handle);
     79        usb_log_info("Controlling new OHCI device `%s'.\n", device->name);
    18680
    18781        return EOK;
    188 #undef CHECK_RET_RETURN
    18982}
    19083/*----------------------------------------------------------------------------*/
  • uspace/drv/ohci/root_hub.c

    r0d92638 ra8ac368  
    3939
    4040#include "root_hub.h"
     41#include "usb/classes/classes.h"
     42#include <usb/request.h>
     43#include <usb/classes/hub.h>
     44
     45/**
     46 *      standart device descriptor for ohci root hub
     47 */
     48static const usb_standard_device_descriptor_t ohci_rh_device_descriptor =
     49{
     50                .configuration_count = 1,
     51                .descriptor_type = USB_DESCTYPE_DEVICE,
     52                .device_class = USB_CLASS_HUB,
     53                .device_protocol = 0,
     54                .device_subclass = 0,
     55                .device_version = 0,
     56                .length = sizeof(usb_standard_device_descriptor_t),
     57                /// \TODO this value is guessed
     58                .max_packet_size = 8,
     59                .vendor_id = 0x16db,
     60                .product_id = 0x0001,
     61                /// \TODO these values migt be different
     62                .str_serial_number = 0,
     63                .usb_spec_version = 0,
     64};
     65
     66/**
     67 * standart configuration descriptor with filled common values
     68 * for ohci root hubs
     69 */
     70static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor =
     71{
     72        /// \TODO some values are default or guessed
     73        .attributes = 1<<7,
     74        .configuration_number = 1,
     75        .descriptor_type = USB_DESCTYPE_CONFIGURATION,
     76        .interface_count = 1,
     77        .length = sizeof(usb_standard_configuration_descriptor_t),
     78        .max_power = 100,
     79        .str_configuration = 0,
     80};
     81
     82/**
     83 * standart ohci root hub interface descriptor
     84 */
     85static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor =
     86{
     87        .alternate_setting = 0,
     88        .descriptor_type = USB_DESCTYPE_INTERFACE,
     89        .endpoint_count = 1,
     90        .interface_class = USB_CLASS_HUB,
     91        /// \TODO is this correct?
     92        .interface_number = 1,
     93        .interface_protocol = 0,
     94        .interface_subclass = 0,
     95        .length = sizeof(usb_standard_interface_descriptor_t),
     96        .str_interface = 0,
     97};
     98
     99/**
     100 * standart ohci root hub endpoint descriptor
     101 */
     102static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor =
     103{
     104        .attributes = USB_TRANSFER_INTERRUPT,
     105        .descriptor_type = USB_DESCTYPE_ENDPOINT,
     106        .endpoint_address = 1 + (1<<7),
     107        .length = sizeof(usb_standard_endpoint_descriptor_t),
     108        .max_packet_size = 8,
     109        .poll_interval = 255,
     110};
    41111
    42112/** Root hub initialization
     
    50120        instance->device = dev;
    51121
     122
    52123        usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff);
    53124
     125        //start generic usb hub driver
     126       
    54127        /* TODO: implement */
    55128        return EOK;
    56129}
    57130/*----------------------------------------------------------------------------*/
     131
     132/**
     133 * create answer to port status_request
     134 *
     135 * Copy content of corresponding port status register to answer buffer.
     136 *
     137 * @param instance root hub instance
     138 * @param port port number, counted from 1
     139 * @param request structure containing both request and response information
     140 * @return error code
     141 */
     142static int process_get_port_status_request(rh_t *instance, uint16_t port,
     143                usb_transfer_batch_t * request){
     144        if(port<1 || port>instance->port_count)
     145                return EINVAL;
     146        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     147        request->transfered_size = 4;
     148        uint32_buffer[0] = instance->registers->rh_port_status[port -1];
     149        return EOK;
     150}
     151
     152/**
     153 * create answer to port status_request
     154 *
     155 * Copy content of hub status register to answer buffer.
     156 *
     157 * @param instance root hub instance
     158 * @param request structure containing both request and response information
     159 * @return error code
     160 */
     161static int process_get_hub_status_request(rh_t *instance,
     162                usb_transfer_batch_t * request){
     163        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     164        //bits, 0,1,16,17
     165        request->transfered_size = 4;
     166        uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
     167        uint32_buffer[0] = mask & instance->registers->rh_status;
     168        return EOK;
     169
     170}
     171
     172/**
     173 * Create hub descriptor used in hub-driver <-> hub communication
     174 *
     175 * This means creating byt array from data in root hub registers. For more
     176 * info see usb hub specification.
     177 *
     178 * @param instance root hub instance
     179 * @param@out out_result pointer to resultant serialized descriptor
     180 * @param@out out_size size of serialized descriptor
     181 */
     182static void usb_create_serialized_hub_descriptor(rh_t *instance,
     183                uint8_t ** out_result,
     184                size_t * out_size) {
     185        //base size
     186        size_t size = 7;
     187        //variable size according to port count
     188        size_t var_size = instance->port_count / 8 +
     189                        ((instance->port_count % 8 > 0) ? 1 : 0);
     190        size += 2 * var_size;
     191        uint8_t * result = (uint8_t*) malloc(size);
     192        bzero(result,size);
     193        //size
     194        result[0] = size;
     195        //descriptor type
     196        result[1] = USB_DESCTYPE_HUB;
     197        result[2] = instance->port_count;
     198        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
     199        result[3] =
     200                        ((hub_desc_reg >> 8) %2) +
     201                        (((hub_desc_reg >> 9) %2) << 1) +
     202                        (((hub_desc_reg >> 10) %2) << 2) +
     203                        (((hub_desc_reg >> 11) %2) << 3) +
     204                        (((hub_desc_reg >> 12) %2) << 4);
     205        result[4] = 0;
     206        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
     207        result[6] = 50;
     208
     209        int port;
     210        for (port = 1; port <= instance->port_count; ++port) {
     211                result[7 + port/8] +=
     212                                ((instance->registers->rh_desc_b >> port)%2) << (port%8);
     213        }
     214        size_t i;
     215        for (i = 0; i < var_size; ++i) {
     216                result[7 + var_size + i] = 255;
     217        }
     218        (*out_result) = result;
     219        (*out_size) = size;
     220}
     221
     222
     223/**
     224 * create answer to status request
     225 *
     226 * This might be either hub status or port status request. If neither,
     227 * ENOTSUP is returned.
     228 * @param instance root hub instance
     229 * @param request structure containing both request and response information
     230 * @return error code
     231 */
     232static int process_get_status_request(rh_t *instance,
     233                usb_transfer_batch_t * request)
     234{
     235        size_t buffer_size = request->buffer_size;
     236        usb_device_request_setup_packet_t * request_packet =
     237                        (usb_device_request_setup_packet_t*)
     238                        request->setup_buffer;
     239
     240        usb_hub_bm_request_type_t request_type = request_packet->request_type;
     241        if(buffer_size<4/*request_packet->length*/){///\TODO
     242                usb_log_warning("requested more data than buffer size\n");
     243                return EINVAL;
     244        }
     245
     246        if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
     247                return process_get_hub_status_request(instance, request);
     248        if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
     249                return process_get_port_status_request(instance, request_packet->index,
     250                                request);
     251        return ENOTSUP;
     252}
     253
     254/**
     255 * create answer to status interrupt consisting of change bitmap
     256 *
     257 * Result contains bitmap where bit 0 indicates change on hub and
     258 * bit i indicates change on i`th port (i>0). For more info see
     259 * Hub and Port status bitmap specification in USB specification.
     260 * @param instance root hub instance
     261 * @param@out buffer pointer to created interrupt mas
     262 * @param@out buffer_size size of created interrupt mask
     263 */
     264static void create_interrupt_mask(rh_t *instance, void ** buffer,
     265                size_t * buffer_size){
     266        int bit_count = instance->port_count + 1;
     267        (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;
     268        (*buffer) = malloc(*buffer_size);
     269        uint8_t * bitmap = (uint8_t*)(*buffer);
     270        uint32_t mask = (1<<16) + (1<<17);
     271        bzero(bitmap,(*buffer_size));
     272        if(instance->registers->rh_status & mask){
     273                bitmap[0] = 1;
     274        }
     275        int port;
     276        mask = 0;
     277        int i;
     278        for(i=16;i<=20;++i)
     279                mask += 1<<i;
     280        for(port = 1; port<=instance->port_count;++port){
     281                if(mask & instance->registers->rh_port_status[port-1]){
     282                        bitmap[(port+1)/8] += 1<<(port%8);
     283                }
     284        }
     285}
     286
     287/**
     288 * create standart configuration descriptor for the root hub instance
     289 * @param instance root hub instance
     290 * @return newly allocated descriptor
     291 */
     292static usb_standard_configuration_descriptor_t *
     293usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){
     294        usb_standard_configuration_descriptor_t * descriptor =
     295                        malloc(sizeof(usb_standard_configuration_descriptor_t));
     296        memcpy(descriptor, &ohci_rh_conf_descriptor,
     297                sizeof(usb_standard_configuration_descriptor_t));
     298        /// \TODO should this include device descriptor?
     299        const size_t hub_descriptor_size = 7 +
     300                        2* (instance->port_count / 8 +
     301                        ((instance->port_count % 8 > 0) ? 1 : 0));
     302        descriptor->total_length =
     303                        sizeof(usb_standard_configuration_descriptor_t)+
     304                        sizeof(usb_standard_endpoint_descriptor_t)+
     305                        sizeof(usb_standard_interface_descriptor_t)+
     306                        hub_descriptor_size;
     307        return descriptor;
     308}
     309
     310/**
     311 * create answer to a descriptor request
     312 *
     313 * This might be a request for standard (configuration, device, endpoint or
     314 * interface) or device specific (hub) descriptor.
     315 * @param instance root hub instance
     316 * @param request structure containing both request and response information
     317 * @return error code
     318 */
     319static int process_get_descriptor_request(rh_t *instance,
     320                usb_transfer_batch_t *request){
     321        usb_device_request_setup_packet_t * setup_request =
     322                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     323        size_t size;
     324        const void * result_descriptor = NULL;
     325        const uint16_t setup_request_value = setup_request->value_high;
     326                        //(setup_request->value_low << 8);
     327        bool del = false;
     328        switch (setup_request_value)
     329        {
     330                case USB_DESCTYPE_HUB: {
     331                        uint8_t * descriptor;
     332                        usb_create_serialized_hub_descriptor(
     333                                instance, &descriptor, &size);
     334                        result_descriptor = descriptor;
     335                        if(result_descriptor) del = true;
     336                        break;
     337                }
     338                case USB_DESCTYPE_DEVICE: {
     339                        usb_log_debug("USB_DESCTYPE_DEVICE\n");
     340                        result_descriptor = &ohci_rh_device_descriptor;
     341                        size = sizeof(ohci_rh_device_descriptor);
     342                        break;
     343                }
     344                case USB_DESCTYPE_CONFIGURATION: {
     345                        usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     346                        usb_standard_configuration_descriptor_t * descriptor =
     347                                        usb_ohci_rh_create_standart_configuration_descriptor(
     348                                                instance);
     349                        result_descriptor = descriptor;
     350                        size = sizeof(usb_standard_configuration_descriptor_t);
     351                        del = true;
     352                        break;
     353                }
     354                case USB_DESCTYPE_INTERFACE: {
     355                        usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     356                        result_descriptor = &ohci_rh_iface_descriptor;
     357                        size = sizeof(ohci_rh_iface_descriptor);
     358                        break;
     359                }
     360                case USB_DESCTYPE_ENDPOINT: {
     361                        usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     362                        result_descriptor = &ohci_rh_ep_descriptor;
     363                        size = sizeof(ohci_rh_ep_descriptor);
     364                        break;
     365                }
     366                default: {
     367                        usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     368                        usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     369                                        setup_request->request_type,
     370                                        setup_request->request,
     371                                        setup_request_value,
     372                                        setup_request->index,
     373                                        setup_request->length
     374                                        );
     375                        return EINVAL;
     376                }
     377        }
     378        if(request->buffer_size < size){
     379                size = request->buffer_size;
     380        }
     381        request->transfered_size = size;
     382        memcpy(request->buffer,result_descriptor,size);
     383        if (del)
     384                free(result_descriptor);
     385        return EOK;
     386}
     387
     388/**
     389 * answer to get configuration request
     390 *
     391 * Root hub works independently on the configuration.
     392 * @param instance root hub instance
     393 * @param request structure containing both request and response information
     394 * @return error code
     395 */
     396static int process_get_configuration_request(rh_t *instance,
     397                usb_transfer_batch_t *request){
     398        //set and get configuration requests do not have any meaning, only dummy
     399        //values are returned
     400        if(request->buffer_size != 1)
     401                return EINVAL;
     402        request->buffer[0] = 1;
     403        request->transfered_size = 1;
     404        return EOK;
     405}
     406
     407/**
     408 * process feature-enabling/disabling request on hub
     409 *
     410 * @param instance root hub instance
     411 * @param feature feature selector
     412 * @param enable enable or disable specified feature
     413 * @return error code
     414 */
     415static int process_hub_feature_set_request(rh_t *instance,
     416                uint16_t feature, bool enable){
     417        if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)
     418                return EINVAL;
     419        instance->registers->rh_status =
     420                        enable ?
     421                        (instance->registers->rh_status | (1<<feature))
     422                        :
     423                        (instance->registers->rh_status & (~(1<<feature)));
     424        /// \TODO any error?
     425        return EOK;
     426}
     427
     428/**
     429 * process feature-enabling/disabling request on hub
     430 *
     431 * @param instance root hub instance
     432 * @param feature feature selector
     433 * @param port port number, counted from 1
     434 * @param enable enable or disable the specified feature
     435 * @return error code
     436 */
     437static int process_port_feature_set_request(rh_t *instance,
     438                uint16_t feature, uint16_t port, bool enable){
     439        if(feature > USB_HUB_FEATURE_C_PORT_RESET)
     440                return EINVAL;
     441        if(port<1 || port>instance->port_count)
     442                return EINVAL;
     443        instance->registers->rh_port_status[port - 1] =
     444                        enable ?
     445                        (instance->registers->rh_port_status[port - 1] | (1<<feature))
     446                        :
     447                        (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));
     448        /// \TODO any error?
     449        return EOK;
     450}
     451
     452/**
     453 * register address to this device
     454 *
     455 * @param instance root hub instance
     456 * @param address new address
     457 * @return error code
     458 */
     459static int process_address_set_request(rh_t *instance,
     460                uint16_t address){
     461        instance->address = address;
     462        return EOK;
     463}
     464
     465/**
     466 * process one of requests that requere output data
     467 *
     468 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or
     469 * USB_DEVREQ_GET_CONFIGURATION.
     470 * @param instance root hub instance
     471 * @param request structure containing both request and response information
     472 * @return error code
     473 */
     474static int process_request_with_output(rh_t *instance,
     475                usb_transfer_batch_t *request){
     476        usb_device_request_setup_packet_t * setup_request =
     477                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     478        if(setup_request->request == USB_DEVREQ_GET_STATUS){
     479                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
     480                return process_get_status_request(instance, request);
     481        }
     482        if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
     483                usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
     484                return process_get_descriptor_request(instance, request);
     485        }
     486        if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
     487                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
     488                return process_get_configuration_request(instance, request);
     489        }
     490        return ENOTSUP;
     491}
     492
     493/**
     494 * process one of requests that carry input data
     495 *
     496 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or
     497 * USB_DEVREQ_SET_CONFIGURATION.
     498 * @param instance root hub instance
     499 * @param request structure containing both request and response information
     500 * @return error code
     501 */
     502static int process_request_with_input(rh_t *instance,
     503                usb_transfer_batch_t *request){
     504        usb_device_request_setup_packet_t * setup_request =
     505                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     506        request->transfered_size = 0;
     507        if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
     508                return ENOTSUP;
     509        }
     510        if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){
     511                //set and get configuration requests do not have any meaning,
     512                //only dummy values are returned
     513                return EOK;
     514        }
     515        return ENOTSUP;
     516}
     517
     518/**
     519 * process one of requests that do not request nor carry additional data
     520 *
     521 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or
     522 * USB_DEVREQ_SET_ADDRESS.
     523 * @param instance root hub instance
     524 * @param request structure containing both request and response information
     525 * @return error code
     526 */
     527static int process_request_without_data(rh_t *instance,
     528                usb_transfer_batch_t *request){
     529        usb_device_request_setup_packet_t * setup_request =
     530                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     531        request->transfered_size = 0;
     532        if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     533                                || setup_request->request == USB_DEVREQ_SET_FEATURE){
     534                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     535                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
     536                        return process_hub_feature_set_request(instance, setup_request->value,
     537                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     538                }
     539                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     540                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
     541                        return process_port_feature_set_request(instance, setup_request->value,
     542                                        setup_request->index,
     543                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     544                }
     545                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
     546                return EINVAL;
     547        }
     548        if(setup_request->request == USB_DEVREQ_SET_ADDRESS){
     549                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
     550                return process_address_set_request(instance, setup_request->value);
     551        }
     552        usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type);
     553        return ENOTSUP;
     554}
     555
     556/**
     557 * process hub control request
     558 *
     559 * If needed, writes answer into the request structure.
     560 * Request can be one of
     561 * USB_DEVREQ_GET_STATUS,
     562 * USB_DEVREQ_GET_DESCRIPTOR,
     563 * USB_DEVREQ_GET_CONFIGURATION,
     564 * USB_DEVREQ_CLEAR_FEATURE,
     565 * USB_DEVREQ_SET_FEATURE,
     566 * USB_DEVREQ_SET_ADDRESS,
     567 * USB_DEVREQ_SET_DESCRIPTOR or
     568 * USB_DEVREQ_SET_CONFIGURATION.
     569 *
     570 * @param instance root hub instance
     571 * @param request structure containing both request and response information
     572 * @return error code
     573 */
     574static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){
     575        int opResult;
     576        if (request->setup_buffer) {
     577                if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     578                        usb_log_error("setup packet too small\n");
     579                        return EINVAL;
     580                }
     581                usb_log_info("CTRL packet: %s.\n",
     582                        usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     583                usb_device_request_setup_packet_t * setup_request =
     584                                (usb_device_request_setup_packet_t*)request->setup_buffer;
     585                if(
     586                        setup_request->request == USB_DEVREQ_GET_STATUS
     587                        || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     588                        || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     589                ){
     590                        usb_log_debug("processing request with output\n");
     591                        opResult = process_request_with_output(instance,request);
     592                }else if(
     593                        setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     594                        || setup_request->request == USB_DEVREQ_SET_FEATURE
     595                        || setup_request->request == USB_DEVREQ_SET_ADDRESS
     596                ){
     597                        usb_log_debug("processing request without additional data\n");
     598                        opResult = process_request_without_data(instance,request);
     599                }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     600                                || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     601                ){
     602                        usb_log_debug("processing request with input\n");
     603                        opResult = process_request_with_input(instance,request);
     604                }else{
     605                        usb_log_warning("received unsuported request: %d\n",
     606                                        setup_request->request
     607                                        );
     608                        opResult = ENOTSUP;
     609                }
     610        }else{
     611                usb_log_error("root hub received empty transaction?");
     612                opResult = EINVAL;
     613        }
     614        return opResult;
     615}
     616
     617/**
     618 * process root hub request
     619 *
     620 * @param instance root hub instance
     621 * @param request structure containing both request and response information
     622 * @return error code
     623 */
    58624int rh_request(rh_t *instance, usb_transfer_batch_t *request)
    59625{
    60626        assert(instance);
    61627        assert(request);
    62         /* TODO: implement */
    63         if (request->setup_buffer) {
    64                 usb_log_info("Root hub got SETUP packet: %s.\n",
    65                     usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
    66         }
    67         usb_log_error("Root hub request processing not implemented.\n");
    68         usb_transfer_batch_finish(request, ENOTSUP);
     628        int opResult;
     629        if(request->transfer_type == USB_TRANSFER_CONTROL){
     630                usb_log_info("Root hub got CONTROL packet\n");
     631                opResult = process_ctrl_request(instance,request);
     632        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
     633                usb_log_info("Root hub got INTERRUPT packet\n");
     634                void * buffer;
     635                create_interrupt_mask(instance, &buffer,
     636                        &(request->transfered_size));
     637                memcpy(request->transport_buffer,buffer, request->transfered_size);
     638                opResult = EOK;
     639        }else{
     640                opResult = EINVAL;
     641        }
     642        usb_transfer_batch_finish(request, opResult);
    69643        return EOK;
    70644}
    71645/*----------------------------------------------------------------------------*/
     646
     647
    72648void rh_interrupt(rh_t *instance)
    73649{
    74         usb_log_error("Root hub interrupt not implemented.\n");
    75         /* TODO: implement */
     650        usb_log_info("Whoa whoa wait, I`m not supposed to receive any interrupts, am I?\n");
     651        /* TODO: implement? */
    76652}
    77653/**
  • uspace/drv/ohci/root_hub.h

    r0d92638 ra8ac368  
    4141#include "batch.h"
    4242
     43/**
     44 * ohci root hub representation
     45 */
    4346typedef struct rh {
     47        /** pointer to ohci driver registers */
    4448        ohci_regs_t *registers;
     49        /** usb address of the root hub */
    4550        usb_address_t address;
     51        /** ddf device information */
    4652        ddf_dev_t *device;
     53        /** hub port count */
     54        int port_count;
    4755} rh_t;
    4856
  • uspace/drv/pciintel/pci.c

    r0d92638 ra8ac368  
    9595        sysarg_t i8259;
    9696
    97         int irc_phone = -1;
    98         int irc_service = -1;
    99 
    100         if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
    101                 irc_service = SERVICE_APIC;
    102         } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
    103                 irc_service = SERVICE_I8259;
    104         }
    105 
    106         if (irc_service == -1) {
    107                 return false;
    108         }
    109 
    110         irc_phone = service_connect_blocking(irc_service, 0, 0);
     97        int irc_phone = ENOTSUP;
     98
     99        if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
     100            || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
     101                irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
     102        }
     103
    111104        if (irc_phone < 0) {
    112105                return false;
  • uspace/drv/uhci-hcd/Makefile

    r0d92638 ra8ac368  
    4040        root_hub.c \
    4141        hw_struct/transfer_descriptor.c \
     42        utils/slab.c \
    4243        pci.c \
    4344        batch.c
  • uspace/drv/uhci-hcd/batch.c

    r0d92638 ra8ac368  
    4848        qh_t *qh;
    4949        td_t *tds;
    50         size_t packets;
     50        size_t transfers;
    5151        usb_device_keeper_t *manager;
    5252} uhci_batch_t;
     
    6464 * @param[in] target Device and endpoint target of the transaction.
    6565 * @param[in] transfer_type Interrupt, Control or Bulk.
    66  * @param[in] max_packet_size maximum allowed size of data packets.
     66 * @param[in] max_packet_size maximum allowed size of data transfers.
    6767 * @param[in] speed Speed of the transaction.
    6868 * @param[in] buffer Data source/destination.
     
    7777 * NULL otherwise.
    7878 *
    79  * Determines the number of needed packets (TDs). Prepares a transport buffer
     79 * Determines the number of needed transfers (TDs). Prepares a transport buffer
    8080 * (that is accessible by the hardware). Initializes parameters needed for the
    8181 * transaction and callback.
     
    117117        instance->private_data = data;
    118118
    119         data->packets = (buffer_size + max_packet_size - 1) / max_packet_size;
     119        data->transfers = (buffer_size + max_packet_size - 1) / max_packet_size;
    120120        if (transfer_type == USB_TRANSFER_CONTROL) {
    121                 data->packets += 2;
    122         }
    123 
    124         data->tds = malloc32(sizeof(td_t) * data->packets);
     121                data->transfers += 2;
     122        }
     123
     124        data->tds = malloc32(sizeof(td_t) * data->transfers);
    125125        CHECK_NULL_DISPOSE_RETURN(
    126126            data->tds, "Failed to allocate transfer descriptors.\n");
    127         bzero(data->tds, sizeof(td_t) * data->packets);
     127        bzero(data->tds, sizeof(td_t) * data->transfers);
    128128
    129129        data->qh = malloc32(sizeof(qh_t));
     
    166166        assert(data);
    167167
    168         usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",
    169             instance, data->packets);
     168        usb_log_debug2("Batch(%p) checking %d transfer(s) for completion.\n",
     169            instance, data->transfers);
    170170        instance->transfered_size = 0;
    171171        size_t i = 0;
    172         for (;i < data->packets; ++i) {
     172        for (;i < data->transfers; ++i) {
    173173                if (td_is_active(&data->tds[i])) {
    174174                        return false;
     
    298298 *
    299299 * @param[in] instance Batch structure to use.
    300  * @param[in] pid to use for data packets.
     300 * @param[in] pid Pid to use for data transfers.
    301301 *
    302302 * Packets with alternating toggle bit and supplied pid value.
    303  * The last packet is marked with IOC flag.
     303 * The last transfer is marked with IOC flag.
    304304 */
    305305void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
     
    314314        assert(toggle == 0 || toggle == 1);
    315315
    316         size_t packet = 0;
     316        size_t transfer = 0;
    317317        size_t remain_size = instance->buffer_size;
    318318        while (remain_size > 0) {
     
    325325                    remain_size : instance->max_packet_size;
    326326
    327                 td_t *next_packet = (packet + 1 < data->packets)
    328                     ? &data->tds[packet + 1] : NULL;
    329 
    330                 assert(packet < data->packets);
     327                td_t *next_transfer = (transfer + 1 < data->transfers)
     328                    ? &data->tds[transfer + 1] : NULL;
     329
     330                assert(transfer < data->transfers);
    331331                assert(packet_size <= remain_size);
    332332
    333333                td_init(
    334                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     334                    &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
    335335                    toggle, false, low_speed, instance->target, pid, trans_data,
    336                     next_packet);
     336                    next_transfer);
    337337
    338338
    339339                toggle = 1 - toggle;
    340340                remain_size -= packet_size;
    341                 ++packet;
    342         }
    343         td_set_ioc(&data->tds[packet - 1]);
     341                ++transfer;
     342        }
     343        td_set_ioc(&data->tds[transfer - 1]);
    344344        usb_device_keeper_set_toggle(data->manager, instance->target,
    345345            instance->direction, toggle);
     
    349349 *
    350350 * @param[in] instance Batch structure to use.
    351  * @param[in] data_stage to use for data packets.
    352  * @param[in] status_stage to use for data packets.
     351 * @param[in] data_stage Pid to use for data transfers.
     352 * @param[in] status_stage Pid to use for data transfers.
    353353 *
    354354 * Setup stage with toggle 0 and USB_PID_SETUP.
    355355 * Data stage with alternating toggle and pid supplied by parameter.
    356356 * Status stage with toggle 1 and pid supplied by parameter.
    357  * The last packet is marked with IOC.
     357 * The last transfer is marked with IOC.
    358358 */
    359359void batch_control(usb_transfer_batch_t *instance,
     
    363363        uhci_batch_t *data = instance->private_data;
    364364        assert(data);
    365         assert(data->packets >= 2);
     365        assert(data->transfers >= 2);
    366366
    367367        const bool low_speed = instance->speed == USB_SPEED_LOW;
     
    374374
    375375        /* data stage */
    376         size_t packet = 1;
     376        size_t transfer = 1;
    377377        size_t remain_size = instance->buffer_size;
    378378        while (remain_size > 0) {
     
    388388
    389389                td_init(
    390                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     390                    &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
    391391                    toggle, false, low_speed, instance->target, data_stage,
    392                     control_data, &data->tds[packet + 1]);
    393 
    394                 ++packet;
    395                 assert(packet < data->packets);
     392                    control_data, &data->tds[transfer + 1]);
     393
     394                ++transfer;
     395                assert(transfer < data->transfers);
    396396                assert(packet_size <= remain_size);
    397397                remain_size -= packet_size;
     
    399399
    400400        /* status stage */
    401         assert(packet == data->packets - 1);
     401        assert(transfer == data->transfers - 1);
    402402
    403403        td_init(
    404             &data->tds[packet], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
     404            &data->tds[transfer], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
    405405            instance->target, status_stage, NULL, NULL);
    406         td_set_ioc(&data->tds[packet]);
     406        td_set_ioc(&data->tds[transfer]);
    407407
    408408        usb_log_debug2("Control last TD status: %x.\n",
    409             data->tds[packet].status);
     409            data->tds[transfer].status);
    410410}
    411411/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/hc.c

    r0d92638 ra8ac368  
    6767static int hc_debug_checker(void *arg);
    6868
    69 static bool allowed_usb_packet(
     69static bool usb_is_allowed(
    7070    bool low_speed, usb_transfer_type_t transfer, size_t size);
    7171/*----------------------------------------------------------------------------*/
     
    223223        ret = instance ? EOK : ENOMEM;
    224224        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
    225         usb_log_debug("Initialized frame list.\n");
     225        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    226226
    227227        /* Set all frames to point to the first queue head */
     
    323323        assert(batch);
    324324        const int low_speed = (batch->speed == USB_SPEED_LOW);
    325         if (!allowed_usb_packet(
     325        if (!usb_is_allowed(
    326326            low_speed, batch->transfer_type, batch->max_packet_size)) {
    327327                usb_log_warning(
    328                     "Invalid USB packet specified %s SPEED %d %zu.\n",
     328                    "Invalid USB transfer specified %s SPEED %d %zu.\n",
    329329                    low_speed ? "LOW" : "FULL" , batch->transfer_type,
    330330                    batch->max_packet_size);
     
    336336            instance->transfers[batch->speed][batch->transfer_type];
    337337        assert(list);
     338        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     339                usb_device_keeper_use_control(
     340                    &instance->manager, batch->target.address);
     341        }
    338342        transfer_list_add_batch(list, batch);
    339343
     
    357361        /* Lower 2 bits are transaction error and transaction complete */
    358362        if (status & 0x3) {
    359                 transfer_list_remove_finished(&instance->transfers_interrupt);
    360                 transfer_list_remove_finished(&instance->transfers_control_slow);
    361                 transfer_list_remove_finished(&instance->transfers_control_full);
    362                 transfer_list_remove_finished(&instance->transfers_bulk_full);
     363                LIST_INITIALIZE(done);
     364                transfer_list_remove_finished(
     365                    &instance->transfers_interrupt, &done);
     366                transfer_list_remove_finished(
     367                    &instance->transfers_control_slow, &done);
     368                transfer_list_remove_finished(
     369                    &instance->transfers_control_full, &done);
     370                transfer_list_remove_finished(
     371                    &instance->transfers_bulk_full, &done);
     372
     373                while (!list_empty(&done)) {
     374                        link_t *item = done.next;
     375                        list_remove(item);
     376                        usb_transfer_batch_t *batch =
     377                            list_get_instance(item, usb_transfer_batch_t, link);
     378                        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     379                                usb_device_keeper_release_control(
     380                                    &instance->manager, batch->target.address);
     381                        }
     382                        batch->next_step(batch);
     383                }
    363384        }
    364385        /* bits 4 and 5 indicate hc error */
     
    471492}
    472493/*----------------------------------------------------------------------------*/
    473 /** Check transfer packets, for USB validity
     494/** Check transfers for USB validity
    474495 *
    475496 * @param[in] low_speed Transfer speed.
    476497 * @param[in] transfer Transer type
    477  * @param[in] size Maximum size of used packets
     498 * @param[in] size Size of data packets
    478499 * @return True if transaction is allowed by USB specs, false otherwise
    479500 */
    480 bool allowed_usb_packet(
     501bool usb_is_allowed(
    481502    bool low_speed, usb_transfer_type_t transfer, size_t size)
    482503{
  • uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.h

    r0d92638 ra8ac368  
    108108}
    109109/*----------------------------------------------------------------------------*/
    110 /** Check whether less than max data were recieved and packet is marked as SPD.
     110/** Check whether less than max data were received on SPD marked transfer.
    111111 *
    112112 * @param[in] instance TD structure to use.
    113  * @return True if packet is short (less than max bytes and SPD set), false
    114  *     otherwise.
     113 * @return True if data packet is short (less than max bytes and SPD set),
     114 * false otherwise.
    115115 */
    116116static inline bool td_is_short(td_t *instance)
  • uspace/drv/uhci-hcd/iface.c

    r0d92638 ra8ac368  
    279279 * @param[in] target USB device to write to.
    280280 * @param[in] max_packet_size maximum size of data packet the device accepts.
    281  * @param[in] setup_data Data to send with SETUP packet.
    282  * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     281 * @param[in] setup_data Data to send with SETUP transfer.
     282 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
    283283 * @param[in] data Source of data.
    284284 * @param[in] size Size of data source.
  • uspace/drv/uhci-hcd/root_hub.c

    r0d92638 ra8ac368  
    4848 * @return Error code.
    4949 */
    50 int rh_init(
    51     rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
     50int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
    5251{
    5352        assert(fun);
  • uspace/drv/uhci-hcd/transfer_list.c

    r0d92638 ra8ac368  
    5858        }
    5959        instance->queue_head_pa = addr_to_phys(instance->queue_head);
     60        usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n",
     61            name, instance->queue_head, instance->queue_head_pa);
    6062
    6163        qh_init(instance->queue_head);
     
    9193 * The batch is added to the end of the list and queue.
    9294 */
    93 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch)
     95void transfer_list_add_batch(
     96    transfer_list_t *instance, usb_transfer_batch_t *batch)
    9497{
    9598        assert(instance);
     
    117120        qh_set_next_qh(last_qh, pa);
    118121
     122        asm volatile ("": : :"memory");
     123
    119124        /* Add to the driver list */
    120125        list_append(&batch->link, &instance->batch_list);
     
    136141 * this transfer list leading to the deadlock if its done inline.
    137142 */
    138 void transfer_list_remove_finished(transfer_list_t *instance)
    139 {
    140         assert(instance);
    141 
    142         LIST_INITIALIZE(done);
     143void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
     144{
     145        assert(instance);
     146        assert(done);
    143147
    144148        fibril_mutex_lock(&instance->guard);
     
    146150        while (current != &instance->batch_list) {
    147151                link_t *next = current->next;
    148                 usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link);
     152                usb_transfer_batch_t *batch =
     153                    list_get_instance(current, usb_transfer_batch_t, link);
    149154
    150155                if (batch_is_complete(batch)) {
    151156                        /* Save for post-processing */
    152157                        transfer_list_remove_batch(instance, batch);
    153                         list_append(current, &done);
     158                        list_append(current, done);
    154159                }
    155160                current = next;
     
    157162        fibril_mutex_unlock(&instance->guard);
    158163
    159         while (!list_empty(&done)) {
    160                 link_t *item = done.next;
    161                 list_remove(item);
    162                 usb_transfer_batch_t *batch = list_get_instance(item, usb_transfer_batch_t, link);
    163                 batch->next_step(batch);
    164         }
    165164}
    166165/*----------------------------------------------------------------------------*/
     
    174173        while (!list_empty(&instance->batch_list)) {
    175174                link_t *current = instance->batch_list.next;
    176                 usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link);
     175                usb_transfer_batch_t *batch =
     176                    list_get_instance(current, usb_transfer_batch_t, link);
    177177                transfer_list_remove_batch(instance, batch);
    178178                usb_transfer_batch_finish(batch, EIO);
     
    189189 * Does not lock the transfer list, caller is responsible for that.
    190190 */
    191 void transfer_list_remove_batch(transfer_list_t *instance, usb_transfer_batch_t *batch)
     191void transfer_list_remove_batch(
     192    transfer_list_t *instance, usb_transfer_batch_t *batch)
    192193{
    193194        assert(instance);
     
    210211        } else {
    211212                usb_transfer_batch_t *prev =
    212                     list_get_instance(batch->link.prev, usb_transfer_batch_t, link);
     213                    list_get_instance(
     214                        batch->link.prev, usb_transfer_batch_t, link);
    213215                assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK)
    214216                    == addr_to_phys(batch_qh(batch)));
     
    216218                qpos = "NOT FIRST";
    217219        }
     220        asm volatile ("": : :"memory");
    218221        /* Remove from the batch list */
    219222        list_remove(&batch->link);
  • uspace/drv/uhci-hcd/transfer_list.h

    r0d92638 ra8ac368  
    6767void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);
    6868
    69 void transfer_list_remove_finished(transfer_list_t *instance);
     69void transfer_list_remove_finished(transfer_list_t *instance, link_t *done);
    7070
    7171void transfer_list_abort_all(transfer_list_t *instance);
  • uspace/drv/uhci-hcd/uhci.c

    r0d92638 ra8ac368  
    4444#include "pci.h"
    4545
    46 
    4746/** IRQ handling callback, identifies device
    4847 *
     
    108107/*----------------------------------------------------------------------------*/
    109108static ddf_dev_ops_t hc_ops = {
    110         .interfaces[USB_DEV_IFACE] = &usb_iface,
     109//      .interfaces[USB_DEV_IFACE] = &usb_iface,
    111110        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    112111};
     
    175174
    176175        bool interrupts = false;
     176#ifdef CONFIG_USBHC_NO_INTERRUPTS
     177        usb_log_warning("Interrupts disabled in OS config, " \
     178            "falling back to polling.\n");
     179#else
    177180        ret = pci_enable_interrupts(device);
    178181        if (ret != EOK) {
    179                 usb_log_warning(
    180                     "Failed(%d) to enable interrupts, fall back to polling.\n",
    181                     ret);
     182                usb_log_warning("Failed to enable interrupts: %s.\n",
     183                    str_error(ret));
     184                usb_log_info("HW interrupts not available, " \
     185                    "falling back to polling.\n");
    182186        } else {
    183187                usb_log_debug("Hw interrupts enabled.\n");
    184188                interrupts = true;
    185189        }
     190#endif
    186191
    187192        instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
  • uspace/drv/uhci-hcd/utils/malloc32.h

    r0d92638 ra8ac368  
    4040#include <as.h>
    4141
     42#include "slab.h"
     43
    4244#define UHCI_STRCUTURES_ALIGNMENT 16
    4345#define UHCI_REQUIRED_PAGE_SIZE 4096
     46
    4447
    4548/** Get physical address translation
     
    5457
    5558        uintptr_t result;
    56         int ret = as_get_physical_mapping(addr, &result);
     59        const int ret = as_get_physical_mapping(addr, &result);
     60        assert(ret == EOK);
    5761
    5862        if (ret != EOK)
     
    6670 * @return Address of the alligned and big enough memory place, NULL on failure.
    6771 */
    68 static inline void * malloc32(size_t size)
    69         { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); }
     72static inline void * malloc32(size_t size) {
     73        if (size <= SLAB_ELEMENT_SIZE)
     74                return slab_malloc_g();
     75        assert(false);
     76        return memalign(UHCI_STRCUTURES_ALIGNMENT, size);
     77}
    7078/*----------------------------------------------------------------------------*/
    7179/** Physical mallocator simulator
     
    7381 * @param[in] addr Address of the place allocated by malloc32
    7482 */
    75 static inline void free32(void *addr)
    76         { if (addr) free(addr); }
     83static inline void free32(void *addr) {
     84        if (!addr)
     85                return;
     86        if (slab_in_range_g(addr))
     87                return slab_free_g(addr);
     88        free(addr);
     89}
    7790/*----------------------------------------------------------------------------*/
    7891/** Create 4KB page mapping
     
    8295static inline void * get_page(void)
    8396{
    84         void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
    85         assert(free_address);
     97        void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
     98        assert(free_address); /* TODO: remove this assert */
    8699        if (free_address == 0)
    87100                return NULL;
    88         void* ret =
    89           as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
     101        void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
    90102                  AS_AREA_READ | AS_AREA_WRITE);
    91103        if (ret != free_address)
  • uspace/drv/usbhub/port_status.h

    r0d92638 ra8ac368  
    3030 */
    3131
    32 #ifndef PORT_STATUS_H
    33 #define PORT_STATUS_H
     32#ifndef HUB_PORT_STATUS_H
     33#define HUB_PORT_STATUS_H
    3434
    3535#include <bool.h>
     
    7979
    8080/**
     81 * set the device request to be a port feature enable request
     82 * @param request
     83 * @param port
     84 * @param feature_selector
     85 */
     86static inline void usb_hub_set_enable_port_feature_request(
     87usb_device_request_setup_packet_t * request, uint16_t port,
     88                uint16_t feature_selector
     89){
     90        request->index = port;
     91        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     92        request->request = USB_HUB_REQUEST_SET_FEATURE;
     93        request->value = feature_selector;
     94        request->length = 0;
     95}
     96
     97
     98/**
    8199 * set the device request to be a port enable request
    82100 * @param request
     
    191209        request->length = 0;
    192210}
     211
    193212
    194213/** get i`th bit of port status */
     
    335354
    336355
    337 #endif  /* PORT_STATUS_H */
     356#endif  /* HUB_PORT_STATUS_H */
    338357
    339358/**
  • uspace/drv/usbhub/usbhub.c

    r0d92638 ra8ac368  
    5353#include "usb/classes/classes.h"
    5454
     55
     56static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     57                usb_speed_t speed);
     58
     59static int usb_hub_trigger_connecting_non_removable_devices(
     60                usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
     61
     62/**
     63 * control loop running in hub`s fibril
     64 *
     65 * Hub`s fibril periodically asks for changes on hub and if needded calls
     66 * change handling routine.
     67 * @warning currently hub driver asks for changes once a second
     68 * @param hub_info_param hub representation pointer
     69 * @return zero
     70 */
    5571int usb_hub_control_loop(void * hub_info_param){
    5672        usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
     
    91107
    92108/**
    93  * Load hub-specific information into hub_info structure.
     109 * Load hub-specific information into hub_info structure and process if needed
    94110 *
    95111 * Particularly read port count and initialize structure holding port
    96  * information.
     112 * information. If there are non-removable devices, start initializing them.
    97113 * This function is hub-specific and should be run only after the hub is
    98114 * configured using usb_hub_set_configuration function.
    99  * @param hub_info pointer to structure with usb hub data
     115 * @param hub_info hub representation
    100116 * @return error code
    101117 */
    102 static int usb_hub_get_hub_specific_info(usb_hub_info_t * hub_info){
     118static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){
    103119        // get hub descriptor
    104120        usb_log_debug("creating serialized descriptor\n");
     
    107123
    108124        /* this was one fix of some bug, should not be needed anymore
     125         * these lines allow to reset hub once more, it can be used as
     126         * brute-force initialization for non-removable devices
    109127        int opResult = usb_request_set_configuration(&result->endpoints.control, 1);
    110128        if(opResult!=EOK){
     
    141159                hub_info->attached_devs[i].address=0;
    142160        }
     161        //handle non-removable devices
     162        usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
    143163        usb_log_debug2("freeing data\n");
    144164        free(serialized_descriptor);
     
    152172 * Check whether there is at least one configuration and sets the first one.
    153173 * This function should be run prior to running any hub-specific action.
    154  * @param hub_info
    155  * @return
     174 * @param hub_info hub representation
     175 * @return error code
    156176 */
    157177static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
     
    162182            std_descriptor->configuration_count);
    163183        if(std_descriptor->configuration_count<1){
    164                 usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE\n");
    165                 //shouldn`t I return?
    166                 //definitely
     184                usb_log_error("there are no configurations available\n");
    167185                return EINVAL;
    168186        }
     
    220238        }
    221239        //get port count and create attached_devs
    222         opResult = usb_hub_get_hub_specific_info(hub_info);
     240        opResult = usb_hub_process_hub_specific_info(hub_info);
    223241        if(opResult!=EOK){
    224242                usb_log_error("could not set hub configuration, errno %d\n",opResult);
     
    258276//*********************************************
    259277//
    260 //  hub driver code, main loop
     278//  hub driver code, main loop and port handling
    261279//
    262280//*********************************************
     281
     282/**
     283 * triggers actions to connect non0removable devices
     284 *
     285 * This will trigger operations leading to activated non-removable device.
     286 * Control pipe of the hub must be open fo communication.
     287 * @param hub hub representation
     288 * @param descriptor usb hub descriptor
     289 * @return error code
     290 */
     291static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub,
     292                usb_hub_descriptor_t * descriptor)
     293{
     294        usb_log_info("attaching non-removable devices(if any)\n");
     295        usb_device_request_setup_packet_t request;
     296        int opResult;
     297        size_t rcvd_size;
     298        usb_port_status_t status;
     299        uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;
     300        int port;
     301        for(port=1;port<=descriptor->ports_count;++port){
     302                bool is_non_removable =
     303                                ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;
     304                if(is_non_removable){
     305                        usb_log_debug("non-removable device on port %d\n",port);
     306                        usb_hub_set_port_status_request(&request, port);
     307                        opResult = usb_pipe_control_read(
     308                                        hub->control_pipe,
     309                                        &request, sizeof(usb_device_request_setup_packet_t),
     310                                        &status, 4, &rcvd_size
     311                                        );
     312                        if (opResult != EOK) {
     313                                usb_log_error("could not get port status of port %d errno:%d\n",
     314                                                port, opResult);
     315                                return opResult;
     316                        }
     317                        //set the status change bit, so it will be noticed in driver loop
     318                        if(usb_port_dev_connected(&status)){
     319                                usb_hub_set_enable_port_feature_request(&request, port,
     320                                                USB_HUB_FEATURE_C_PORT_CONNECTION);
     321                                opResult = usb_pipe_control_read(
     322                                                hub->control_pipe,
     323                                                &request, sizeof(usb_device_request_setup_packet_t),
     324                                                &status, 4, &rcvd_size
     325                                                );
     326                                if (opResult != EOK) {
     327                                        usb_log_warning(
     328                                                        "could not set port change on port %d errno:%d\n",
     329                                                        port, opResult);
     330                                }
     331                        }
     332                }
     333        }
     334        return EOK;
     335}
     336
    263337
    264338/**
     
    282356/**
    283357 * Reset the port with new device and reserve the default address.
    284  * @param hc
    285  * @param port
    286  * @param target
     358 * @param hub hub representation
     359 * @param port port number, starting from 1
     360 * @param speed transfer speed of attached device, one of low, full or high
    287361 */
    288362static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     
    317391        if (opResult != EOK) {
    318392                usb_log_error("something went wrong when reseting a port %d\n",opResult);
    319                 //usb_hub_release_default_address(hc);
    320393                usb_hub_release_default_address(hub);
    321394        }
     
    325398/**
    326399 * Finalize adding new device after port reset
    327  * @param hc
    328  * @param port
    329  * @param target
     400 *
     401 * Set device`s address and start it`s driver.
     402 * @param hub hub representation
     403 * @param port port number, starting from 1
     404 * @param speed transfer speed of attached device, one of low, full or high
    330405 */
    331406static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
     
    377452        }
    378453
    379 
    380454        //opResult = usb_hub_release_default_address(hc);
    381455        opResult = usb_hub_release_default_address(hub);
     
    412486
    413487/**
    414  * Unregister device address in hc
    415  * @param hc
    416  * @param port
    417  * @param target
     488 * routine called when a device on port has been removed
     489 *
     490 * If the device on port had default address, it releases default address.
     491 * Otherwise does not do anything, because DDF does not allow to remove device
     492 * from it`s device tree.
     493 * @param hub hub representation
     494 * @param port port number, starting from 1
    418495 */
    419496static void usb_hub_removed_device(
     
    454531 * Turn off the power on the port.
    455532 *
    456  * @param hub
    457  * @param port
     533 * @param hub hub representation
     534 * @param port port number, starting from 1
    458535 */
    459536static void usb_hub_over_current( usb_hub_info_t * hub,
     
    470547/**
    471548 * Process interrupts on given hub port
    472  * @param hc
    473  * @param port
    474  * @param target
     549 *
     550 * Accepts connection, over current and port reset change.
     551 * @param hub hub representation
     552 * @param port port number, starting from 1
    475553 */
    476554static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     
    543621
    544622/**
    545  * Check changes on particular hub
    546  * @param hub_info_param pointer to usb_hub_info_t structure
    547  * @return error code if there is problem when initializing communication with
    548  * hub, EOK otherwise
     623 * check changes on hub
     624 *
     625 * Handles changes on each port with a status change.
     626 * @param hub_info hub representation
     627 * @return error code
    549628 */
    550629int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
  • uspace/drv/usbkbd/kbddev.c

    r0d92638 ra8ac368  
    602602//      int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    603603//          callbacks, kbd_dev);
     604        usb_hid_report_path_t *path = usb_hid_report_path();
     605        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     606       
    604607        int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
    605             actual_size, callbacks, kbd_dev);
     608            actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev);
     609
     610        usb_hid_report_path_free (path);
    606611       
    607612        if (rc != EOK) {
     
    704709       
    705710        /* TODO: does not work! */
    706         if (dev->pipes[USB_KBD_POLL_EP_NO].interface_no < 0) {
     711        if (!dev->pipes[USB_KBD_POLL_EP_NO].present) {
    707712                usb_log_warning("Required endpoint not found - probably not "
    708713                    "a supported device.\n");
     
    747752         * TODO: make more general
    748753         */
    749         usb_hid_report_path_t path;
    750         path.usage_page = USB_HIDUT_PAGE_KEYBOARD;
     754        usb_hid_report_path_t *path = usb_hid_report_path();
     755        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    751756        kbd_dev->key_count = usb_hid_report_input_length(
    752             kbd_dev->parser, &path);
     757            kbd_dev->parser, path, USB_HID_PATH_COMPARE_STRICT);
     758        usb_hid_report_path_free (path);
    753759       
    754760        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
  • uspace/drv/usbmid/explore.c

    r0d92638 ra8ac368  
    4040#include <usb/request.h>
    4141#include <usb/dp.h>
     42#include <usb/ddfiface.h>
    4243#include "usbmid.h"
     44
     45/** Operations of the device itself. */
     46static ddf_dev_ops_t mid_device_ops = {
     47        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
     48};
    4349
    4450/** Find starting indexes of all interface descriptors in a configuration.
     
    105111 * @return Whether to accept this device from devman.
    106112 */
    107 bool usbmid_explore_device(usbmid_device_t *dev)
     113bool usbmid_explore_device(usb_device_t *dev)
    108114{
    109         usb_standard_device_descriptor_t device_descriptor;
    110         int rc = usb_request_get_device_descriptor(&dev->ctrl_pipe,
    111             &device_descriptor);
    112         if (rc != EOK) {
    113                 usb_log_error("Getting device descriptor failed: %s.\n",
    114                     str_error(rc));
    115                 return false;
    116         }
    117 
    118         if (device_descriptor.device_class != USB_CLASS_USE_INTERFACE) {
     115        int rc;
     116
     117        int dev_class = dev->descriptors.device.device_class;
     118        if (dev_class != USB_CLASS_USE_INTERFACE) {
    119119                usb_log_warning(
    120120                    "Device class: %d (%s), but expected class 0.\n",
    121                     device_descriptor.device_class,
    122                     usb_str_class(device_descriptor.device_class));
     121                    dev_class, usb_str_class(dev_class));
    123122                usb_log_error("Not multi interface device, refusing.\n");
    124123                return false;
    125124        }
    126125
    127         size_t config_descriptor_size;
    128         uint8_t *config_descriptor_raw = NULL;
    129         rc = usb_request_get_full_configuration_descriptor_alloc(
    130             &dev->ctrl_pipe, 0,
    131             (void **) &config_descriptor_raw, &config_descriptor_size);
    132         if (rc != EOK) {
    133                 usb_log_error("Failed getting full config descriptor: %s.\n",
    134                     str_error(rc));
    135                 return false;
    136         }
    137 
    138         usb_standard_configuration_descriptor_t *config_descriptor
    139             = (usb_standard_configuration_descriptor_t *) config_descriptor_raw;
     126        /* Short cuts to save on typing ;-). */
     127        uint8_t *config_descriptor_raw = dev->descriptors.configuration;
     128        size_t config_descriptor_size = dev->descriptors.configuration_size;
     129        usb_standard_configuration_descriptor_t *config_descriptor =
     130            (usb_standard_configuration_descriptor_t *) config_descriptor_raw;
    140131
    141132        size_t *interface_descriptors
     
    154145        if (interface_descriptors_count == (size_t) -1) {
    155146                usb_log_error("Problem parsing configuration descriptor.\n");
    156                 free(config_descriptor_raw);
    157147                free(interface_descriptors);
    158148                return false;
     
    165155                usb_log_error("Failed to set device configuration: %s.\n",
    166156                    str_error(rc));
    167                 free(config_descriptor_raw);
    168157                free(interface_descriptors);
    169158                return false;
     
    172161
    173162        /* Create control function */
    174         ddf_fun_t *ctl_fun = ddf_fun_create(dev->dev, fun_exposed, "ctl");
     163        ddf_fun_t *ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "ctl");
    175164        if (ctl_fun == NULL) {
    176165                usb_log_error("Failed to create control function.\n");
    177                 free(config_descriptor_raw);
    178                 free(interface_descriptors);
    179                 return false;
    180         }
     166                free(interface_descriptors);
     167                return false;
     168        }
     169
     170        ctl_fun->ops = &mid_device_ops;
     171
    181172        rc = ddf_fun_bind(ctl_fun);
    182173        if (rc != EOK) {
    183174                usb_log_error("Failed to bind control function: %s.\n",
    184175                    str_error(rc));
    185                 free(config_descriptor_raw);
    186176                free(interface_descriptors);
    187177                return false;
     
    199189                    (int) interface->interface_number,
    200190                    usb_str_class(interface->interface_class));
    201                 rc = usbmid_spawn_interface_child(dev, &device_descriptor,
     191                rc = usbmid_spawn_interface_child(dev, &dev->descriptors.device,
    202192                    interface);
    203193                if (rc != EOK) {
     
    207197        }
    208198
    209         free(config_descriptor_raw);
    210 
    211199        return true;
    212200}
  • uspace/drv/usbmid/main.c

    r0d92638 ra8ac368  
    4949 * @return Error code.
    5050 */
    51 static int usbmid_add_device(ddf_dev_t *gen_dev)
     51static int usbmid_add_device(usb_device_t *dev)
    5252{
    53         usbmid_device_t *dev = usbmid_device_create(gen_dev);
    54         if (dev == NULL) {
    55                 return ENOMEM;
    56         }
    57 
    58         usb_log_info("Taking care of new MID: addr %d (HC %zu)\n",
    59             dev->wire.address, dev->wire.hc_handle);
     53        usb_log_info("Taking care of new MID `%s'.\n", dev->ddf_dev->name);
    6054
    6155        int rc;
     
    6559                usb_log_error("Failed to start session on control pipe: %s.\n",
    6660                    str_error(rc));
    67                 goto error_leave;
     61                return rc;
    6862        }
    6963
     
    7771
    7872        if (!accept) {
    79                 rc = ENOTSUP;
    80                 goto error_leave;
     73                return ENOTSUP;
    8174        }
    8275
    83         gen_dev->driver_data = dev;
    84 
    8576        return EOK;
    86 
    87 
    88 error_leave:
    89         free(dev);
    90         return rc;
    9177}
    9278
    9379/** USB MID driver ops. */
    94 static driver_ops_t mid_driver_ops = {
     80static usb_driver_ops_t mid_driver_ops = {
    9581        .add_device = usbmid_add_device,
    9682};
    9783
    9884/** USB MID driver. */
    99 static driver_t mid_driver = {
     85static usb_driver_t mid_driver = {
    10086        .name = NAME,
    101         .driver_ops = &mid_driver_ops
     87        .ops = &mid_driver_ops,
     88        .endpoints = NULL
    10289};
    10390
     
    10794
    10895        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    109         return ddf_driver_main(&mid_driver);
     96
     97        return usb_driver_main(&mid_driver);
    11098}
    11199
  • uspace/drv/usbmid/usbmid.c

    r0d92638 ra8ac368  
    7979};
    8080
    81 /** Operations of the device itself. */
    82 static ddf_dev_ops_t mid_device_ops = {
    83         .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
    84 };
    85 
    86 /** Create new USB multi interface device.
    87  *
    88  * @param dev Backing generic DDF device.
    89  * @return New USB MID device.
    90  * @retval NULL Error occured.
    91  */
    92 usbmid_device_t *usbmid_device_create(ddf_dev_t *dev)
    93 {
    94         usbmid_device_t *mid = malloc(sizeof(usbmid_device_t));
    95         if (mid == NULL) {
    96                 usb_log_error("Out of memory (wanted %zu bytes).\n",
    97                     sizeof(usbmid_device_t));
    98                 return NULL;
    99         }
    100 
    101         int rc;
    102         rc = usb_device_connection_initialize_from_device(&mid->wire, dev);
    103         if (rc != EOK) {
    104                 usb_log_error("Failed to initialize `USB wire': %s.\n",
    105                     str_error(rc));
    106                 free(mid);
    107                 return NULL;
    108         }
    109 
    110         rc = usb_pipe_initialize_default_control(&mid->ctrl_pipe,
    111             &mid->wire);
    112         if (rc != EOK) {
    113                 usb_log_error("Failed to initialize control pipe: %s.\n",
    114                     str_error(rc));
    115                 free(mid);
    116                 return NULL;
    117         }
    118         rc = usb_pipe_probe_default_control(&mid->ctrl_pipe);
    119         if (rc != EOK) {
    120                 usb_log_error("Probing default control pipe failed: %s.\n",
    121                     str_error(rc));
    122                 free(mid);
    123                 return NULL;
    124         }
    125 
    126         mid->dev = dev;
    127         (void) &mid_device_ops;
    128 
    129         return mid;
    130 }
    131 
    13281/** Create new interface for USB MID device.
    13382 *
     
    160109 * @return Error code.
    161110 */
    162 int usbmid_spawn_interface_child(usbmid_device_t *parent,
     111int usbmid_spawn_interface_child(usb_device_t *parent,
    163112    const usb_standard_device_descriptor_t *device_descriptor,
    164113    const usb_standard_interface_descriptor_t *interface_descriptor)
     
    182131
    183132        /* Create the device. */
    184         child = ddf_fun_create(parent->dev, fun_inner, child_name);
     133        child = ddf_fun_create(parent->ddf_dev, fun_inner, child_name);
    185134        if (child == NULL) {
    186135                rc = ENOMEM;
  • uspace/drv/usbmid/usbmid.h

    r0d92638 ra8ac368  
    4141#include <usb/pipes.h>
    4242#include <usb/debug.h>
     43#include <usb/devdrv.h>
    4344
    4445#define NAME "usbmid"
    45 
    46 /** USB MID device container. */
    47 typedef struct {
    48         /** Device container. */
    49         ddf_dev_t *dev;
    50 
    51         /** Representation of USB wire. */
    52         usb_device_connection_t wire;
    53         /** Default control pipe. */
    54         usb_pipe_t ctrl_pipe;
    55 } usbmid_device_t;
    56 
    5746
    5847/** Container for single interface in a MID device. */
     
    6554} usbmid_interface_t;
    6655
    67 usbmid_device_t *usbmid_device_create(ddf_dev_t *);
    6856usbmid_interface_t *usbmid_interface_create(ddf_fun_t *, int);
    69 bool usbmid_explore_device(usbmid_device_t *);
    70 int usbmid_spawn_interface_child(usbmid_device_t *,
     57bool usbmid_explore_device(usb_device_t *);
     58int usbmid_spawn_interface_child(usb_device_t *,
    7159    const usb_standard_device_descriptor_t *,
    7260    const usb_standard_interface_descriptor_t *);
  • uspace/lib/c/generic/malloc.c

    r0d92638 ra8ac368  
    240240        size_t asize = ALIGN_UP(size, PAGE_SIZE);
    241241       
    242         astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
     242        astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);
    243243        if (astart == (void *) -1)
    244244                return false;
  • uspace/lib/c/include/ipc/services.h

    r0d92638 ra8ac368  
    4747        SERVICE_DEVMAP,
    4848        SERVICE_DEVMAN,
    49         SERVICE_FHC,
    50         SERVICE_OBIO,
    51         SERVICE_APIC,
    52         SERVICE_I8259,
     49        SERVICE_IRC,
    5350        SERVICE_CLIPBOARD,
    5451        SERVICE_NETWORKING,
  • uspace/lib/fs/libfs.c

    r0d92638 ra8ac368  
    391391                                                if (lflag & L_CREATE)
    392392                                                        (void) ops->destroy(fn);
     393                                                else
     394                                                        (void) ops->node_put(fn);
    393395                                                async_answer_0(rid, rc);
    394396                                        } else {
     
    473475                                        if (lflag & L_CREATE)
    474476                                                (void) ops->destroy(fn);
     477                                        else
     478                                                (void) ops->node_put(fn);
    475479                                        async_answer_0(rid, rc);
    476480                                } else {
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r0d92638 ra8ac368  
    7070 * Description of path of usage pages and usages in report descriptor
    7171 */
     72#define USB_HID_PATH_COMPARE_STRICT                             0
     73#define USB_HID_PATH_COMPARE_END                                1
     74#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    4
     75
    7276typedef struct {
    7377        int32_t usage_page;
     78        int32_t usage;
     79
     80        link_t link;
     81} usb_hid_report_usage_path_t;
     82
     83typedef struct {
     84        int depth;     
     85        link_t link;
    7486} usb_hid_report_path_t;
    7587
     
    7991typedef struct {
    8092        int32_t id;
    81         int32_t usage_page;
    82         int32_t usage; 
    8393        int32_t usage_minimum;
    8494        int32_t usage_maximum;
     
    107117        uint8_t item_flags;
    108118
     119        usb_hid_report_path_t *usage_path;
    109120        link_t link;
    110121} usb_hid_report_item_t;
     
    117128        link_t feature;
    118129} usb_hid_report_parser_t;     
    119 
    120130
    121131
     
    194204int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    195205    const uint8_t *data, size_t size,
     206    usb_hid_report_path_t *path, int flags,
    196207    const usb_hid_report_in_callbacks_t *callbacks, void *arg);
    197208
    198209int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    199         const usb_hid_report_path_t *path);
     210        usb_hid_report_path_t *path, int flags);
    200211
    201212
     
    204215void usb_hid_descriptor_print(usb_hid_report_parser_t *parser);
    205216
     217/* usage path functions */
     218usb_hid_report_path_t *usb_hid_report_path(void);
     219void usb_hid_report_path_free(usb_hid_report_path_t *path);
     220int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage);
     221void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path);
     222void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path);
     223void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data);
     224int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags);
     225int     usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path);
     226
     227
     228// output
     229//      - funkce co vrati cesty poli v output reportu
     230//      - funkce co pro danou cestu nastavi data
     231//      - finalize
     232
    206233#endif
    207234/**
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r0d92638 ra8ac368  
    5151        usb_speed_t speed;
    5252        bool occupied;
     53        bool control_used;
    5354        uint16_t toggle_status[2];
    5455        devman_handle_t handle;
     
    6162        struct usb_device_info devices[USB_ADDRESS_COUNT];
    6263        fibril_mutex_t guard;
    63         fibril_condvar_t default_address_occupied;
     64        fibril_condvar_t change;
    6465        usb_address_t last_address;
    6566} usb_device_keeper_t;
     
    9798    usb_address_t address);
    9899
     100void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     101    usb_address_t address);
     102
     103void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     104    usb_address_t address);
     105
    99106#endif
    100107/**
  • uspace/lib/usb/include/usb/request.h

    r0d92638 ra8ac368  
    4141#include <usb/pipes.h>
    4242#include <usb/descriptor.h>
     43
     44/** USB device status - device is self powered (opposed to bus powered). */
     45#define USB_DEVICE_STATUS_SELF_POWERED ((uint16_t)(1 << 0))
     46
     47/** USB device status - remote wake-up signaling is enabled. */
     48#define USB_DEVICE_STATUS_REMOTE_WAKEUP ((uint16_t)(1 << 1))
     49
     50/** USB endpoint status - endpoint is halted (stalled). */
     51#define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0))
    4352
    4453/** Standard device request. */
  • uspace/lib/usb/src/hidparser.c

    r0d92638 ra8ac368  
    4747
    4848int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    49                              usb_hid_report_item_t *report_item);
     49                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5050int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    51                              usb_hid_report_item_t *report_item);
     51                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5252int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    53                              usb_hid_report_item_t *report_item);
     53                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5454int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    55                              usb_hid_report_item_t *report_item);
     55                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5656
    5757void usb_hid_descriptor_print_list(link_t *head);
     
    6363int usb_pow(int a, int b);
    6464
     65
    6566int usb_pow(int a, int b)
    6667{
     
    8485{
    8586   if(parser == NULL) {
    86         return -1;
     87        return EINVAL;
    8788   }
    8889
     
    110111        int ret;
    111112        usb_hid_report_item_t *report_item=0;
    112         usb_hid_report_item_t *new_report_item;
     113        usb_hid_report_item_t *new_report_item;
     114        usb_hid_report_path_t *usage_path;
     115        usb_hid_report_path_t *tmp_usage_path;
    113116
    114117        size_t offset_input=0;
     
    117120       
    118121
     122        /* parser structure initialization*/
     123        if(usb_hid_parser_init(parser) != EOK) {
     124                return EINVAL;
     125        }
     126       
     127
     128        /*report item initialization*/
    119129        if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
    120130                return ENOMEM;
    121131        }
    122132        memset(report_item, 0, sizeof(usb_hid_report_item_t));
    123        
    124         link_initialize(&(report_item->link)); 
    125 
     133        list_initialize(&(report_item->link)); 
     134
     135        /* usage path context initialization */
     136        if(!(usage_path=usb_hid_report_path())){
     137                return ENOMEM;
     138        }
     139       
    126140        while(i<size){ 
    127141                if(!USB_HID_ITEM_IS_LONG(data[i])){
    128142
    129143                        if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
    130                                 return -1; // TODO ERROR CODE
     144                                return EINVAL; // TODO ERROR CODE
    131145                        }
    132146                       
     
    141155                       
    142156                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    143                                                  item_size,report_item);
     157                                                       item_size,report_item, usage_path);
    144158                        usb_log_debug2("ret: %u\n", ret);
    145159                        switch(ret){
    146160                                case USB_HID_NEW_REPORT_ITEM:
    147161                                        // store report item to report and create the new one
    148                                         usb_log_debug("\nNEW REPORT ITEM: %X",tag);
     162                                        usb_log_debug("\nNEW REPORT ITEM: %X",ret);
     163
     164                                        // store current usage path
     165                                        report_item->usage_path = usage_path;
     166
     167                                        // new current usage path
     168                                        tmp_usage_path = usb_hid_report_path();
     169                                       
     170                                        // copy old path to the new one
     171                                        usb_hid_report_path_clone(tmp_usage_path, usage_path);
     172
     173                                        // swap
     174                                        usage_path = tmp_usage_path;
     175                                        tmp_usage_path = NULL;
     176
    149177                                       
    150178                                        switch(tag) {
     
    184212                                        link_initialize(&(new_report_item->link));
    185213                                        report_item = new_report_item;
    186                                        
     214                                                                               
    187215                                        break;
    188216                                case USB_HID_REPORT_TAG_PUSH:
     
    284312 */
    285313int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    286                              usb_hid_report_item_t *report_item)
     314                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    287315{       
    288316        int ret;
     
    291319                case USB_HID_TAG_CLASS_MAIN:
    292320
    293                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) {
     321                        if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
    294322                                return USB_HID_NEW_REPORT_ITEM;
    295323                        }
     
    301329
    302330                case USB_HID_TAG_CLASS_GLOBAL: 
    303                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);
     331                        return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
    304332                        break;
    305333
    306334                case USB_HID_TAG_CLASS_LOCAL:                   
    307                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);
     335                        return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
    308336                        break;
    309337                default:
     
    323351
    324352int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    325                              usb_hid_report_item_t *report_item)
    326 {
     353                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     354{               
    327355        switch(tag)
    328356        {
     
    335363                       
    336364                case USB_HID_REPORT_TAG_COLLECTION:
    337                         // TODO
     365                        usb_hid_report_path_append_item(usage_path, 0, 0);
     366                                               
    338367                        return USB_HID_NO_ACTION;
    339368                        break;
    340369                       
    341370                case USB_HID_REPORT_TAG_END_COLLECTION:
    342                         /* should be ignored */
     371                        // TODO
     372                        // znici posledni uroven ve vsech usage paths
     373                        // otazka jestli nema nicit dve, respektive novou posledni vynulovat?
     374                        usb_hid_report_remove_last_item(usage_path);
    343375                        return USB_HID_NO_ACTION;
    344376                        break;
     
    361393
    362394int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    363                              usb_hid_report_item_t *report_item)
     395                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    364396{
    365397        // TODO take care about the bit length of data
     
    367399        {
    368400                case USB_HID_REPORT_TAG_USAGE_PAGE:
    369                         report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);
     401                        // zmeni to jenom v poslednim poli aktualni usage path
     402                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL,
     403                                usb_hid_report_tag_data_int32(data,item_size));
    370404                        break;
    371405                case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     
    418452 */
    419453int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    420                              usb_hid_report_item_t *report_item)
     454                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    421455{
    422456        switch(tag)
    423457        {
    424458                case USB_HID_REPORT_TAG_USAGE:
    425                         report_item->usage = usb_hid_report_tag_data_int32(data,item_size);
     459                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,
     460                                usb_hid_report_tag_data_int32(data,item_size));
    426461                        break;
    427462                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     
    491526{
    492527        usb_hid_report_item_t *report_item;
     528        usb_hid_report_usage_path_t *path_item;
     529        link_t *path;
    493530        link_t *item;
    494531       
     
    507544                usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
    508545                usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags));
    509                 usb_log_debug("\tUSAGE: %X\n", report_item->usage);
    510                 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
     546                usb_log_debug("\tUSAGE PATH:\n");
     547
     548                path = report_item->usage_path->link.next;
     549                while(path != &report_item->usage_path->link)   {
     550                        path_item = list_get_instance(path, usb_hid_report_usage_path_t, link);
     551                        usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage);
     552                        path = path->next;
     553                }
     554               
     555               
     556//              usb_log_debug("\tUSAGE: %X\n", report_item->usage);
     557//              usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
    511558                usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
    512559                usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
     
    530577void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
    531578{
     579        if(parser == NULL) {
     580                return;
     581        }
     582       
    532583        usb_log_debug("INPUT:\n");
    533584        usb_hid_descriptor_print_list(&parser->input);
     
    561612       
    562613            report_item = list_get_instance(next, usb_hid_report_item_t, link);
     614
     615                while(!list_empty(&report_item->usage_path->link)) {
     616                        usb_hid_report_remove_last_item(report_item->usage_path);
     617                }
     618
     619               
    563620            next = next->next;
    564621           
     
    600657int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    601658    const uint8_t *data, size_t size,
     659    usb_hid_report_path_t *path, int flags,
    602660    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    603661{
     
    615673        size_t j=0;
    616674
     675        if(parser == NULL) {
     676                return EINVAL;
     677        }
     678
     679       
    617680        // get the size of result keycodes array
    618         usb_hid_report_path_t path;
    619         path.usage_page = BAD_HACK_USAGE_PAGE;
    620         key_count = usb_hid_report_input_length(parser, &path);
     681        key_count = usb_hid_report_input_length(parser, path, flags);
    621682
    622683        if(!(keys = malloc(sizeof(uint8_t) * key_count))){
     
    629690
    630691                item = list_get_instance(list_item, usb_hid_report_item_t, link);
    631                 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
    632                    (item->usage_page == path.usage_page)) {
     692                if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 
     693                   (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
    633694                        for(j=0; j<(size_t)(item->count); j++) {
    634695                                if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
     
    640701                                        // bitmapa
    641702                                        if((item_value = usb_hid_translate_data(item, data, j)) != 0) {
    642                                                 keys[i++] = j + item->usage_minimum;
     703                                                keys[i++] = (item->count - 1 - j) + item->usage_minimum;
    643704                                        }
    644705                                        else {
     
    736797
    737798int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    738         const usb_hid_report_path_t *path)
    739 {
     799        usb_hid_report_path_t *path, int flags)
     800{       
    740801        int ret = 0;
    741802        link_t *item;
    742803        usb_hid_report_item_t *report_item;
    743804
     805        if(parser == NULL) {
     806                return EINVAL;
     807        }
     808       
    744809        item = (&parser->input)->next;
    745810        while(&parser->input != item) {
    746811                report_item = list_get_instance(item, usb_hid_report_item_t, link);
    747812                if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
    748                    (report_item->usage_page == path->usage_page)) {
     813                   (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
    749814                        ret += report_item->count;
    750815                }
     
    757822
    758823
     824/**
     825 *
     826 */
     827int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path,
     828                                    int32_t usage_page, int32_t usage)
     829{       
     830        usb_hid_report_usage_path_t *item;
     831
     832        if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) {
     833                return ENOMEM;
     834        }
     835        list_initialize(&item->link);
     836
     837        item->usage = usage;
     838        item->usage_page = usage_page;
     839       
     840        list_append (&usage_path->link, &item->link);
     841        usage_path->depth++;
     842        return EOK;
     843}
     844
     845/**
     846 *
     847 */
     848void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
     849{
     850        usb_hid_report_usage_path_t *item;
     851       
     852        if(!list_empty(&usage_path->link)){
     853                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);             
     854                list_remove(usage_path->link.prev);
     855                usage_path->depth--;
     856                free(item);
     857        }
     858}
     859
     860/**
     861 *
     862 */
     863void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)
     864{
     865        usb_hid_report_usage_path_t *item;
     866       
     867        if(!list_empty(&usage_path->link)){     
     868                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
     869                memset(item, 0, sizeof(usb_hid_report_usage_path_t));
     870        }
     871}
     872
     873/**
     874 *
     875 */
     876void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data)
     877{
     878        usb_hid_report_usage_path_t *item;
     879       
     880        if(!list_empty(&usage_path->link)){     
     881                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
     882
     883                switch(tag) {
     884                        case USB_HID_TAG_CLASS_GLOBAL:
     885                                item->usage_page = data;
     886                                break;
     887                        case USB_HID_TAG_CLASS_LOCAL:
     888                                item->usage = data;
     889                                break;
     890                }
     891        }
     892       
     893}
     894
     895/**
     896 *
     897 */
     898int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,
     899                                      usb_hid_report_path_t *path,
     900                                      int flags)
     901{
     902        usb_hid_report_usage_path_t *report_item;
     903        usb_hid_report_usage_path_t *path_item;
     904
     905        link_t *report_link;
     906        link_t *path_link;
     907
     908        int only_page;
     909
     910        if(path->depth == 0){
     911                return EOK;
     912        }
     913
     914
     915        if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){
     916                flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY;
     917        }
     918       
     919        switch(flags){
     920                /* path must be completly identical */
     921                case USB_HID_PATH_COMPARE_STRICT:
     922                                if(report_path->depth != path->depth){
     923                                        return 1;
     924                                }
     925
     926                                report_link = report_path->link.next;
     927                                path_link = path->link.next;
     928                       
     929                                while((report_link != &report_path->link) && (path_link != &path->link)) {
     930                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     931                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     932
     933                                        if((report_item->usage_page != path_item->usage_page) ||
     934                                           ((only_page == 0) && (report_item->usage != path_item->usage))) {
     935                                                   return 1;
     936                                        } else {
     937                                                report_link = report_link->next;
     938                                                path_link = path_link->next;                   
     939                                        }
     940                       
     941                                }
     942
     943                                if((report_link == &report_path->link) && (path_link == &path->link)) {
     944                                        return EOK;
     945                                }
     946                                else {
     947                                        return 1;
     948                                }                                               
     949                        break;
     950
     951                /* given path must be the end of the report one*/
     952                case USB_HID_PATH_COMPARE_END:
     953                                report_link = report_path->link.prev;
     954                                path_link = path->link.prev;
     955
     956                                if(list_empty(&path->link)){
     957                                        return EOK;
     958                                }
     959                       
     960                                while((report_link != &report_path->link) && (path_link != &path->link)) {
     961                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     962                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     963
     964                                        if((report_item->usage_page != path_item->usage_page) ||
     965                                           ((only_page == 0) && (report_item->usage != path_item->usage))) {
     966                                                   return 1;
     967                                        } else {
     968                                                report_link = report_link->prev;
     969                                                path_link = path_link->prev;                   
     970                                        }
     971                       
     972                                }
     973
     974                                if(path_link == &path->link) {
     975                                        return EOK;
     976                                }
     977                                else {
     978                                        return 1;
     979                                }                                               
     980                       
     981                        break;
     982
     983                default:
     984                        return EINVAL;
     985        }
     986       
     987       
     988       
     989       
     990}
     991
     992/**
     993 *
     994 */
     995usb_hid_report_path_t *usb_hid_report_path(void)
     996{
     997        usb_hid_report_path_t *path;
     998        path = malloc(sizeof(usb_hid_report_path_t));
     999        if(!path){
     1000                return NULL;
     1001        }
     1002        else {
     1003                path->depth = 0;
     1004                list_initialize(&path->link);
     1005                return path;
     1006        }
     1007}
     1008
     1009/**
     1010 *
     1011 */
     1012void usb_hid_report_path_free(usb_hid_report_path_t *path)
     1013{
     1014        while(!list_empty(&path->link)){
     1015                usb_hid_report_remove_last_item(path);
     1016        }
     1017}
     1018
     1019
     1020/**
     1021 *
     1022 */
     1023int     usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path)
     1024{
     1025        usb_hid_report_usage_path_t *path_item;
     1026        link_t *path_link;
     1027
     1028       
     1029        if(list_empty(&usage_path->link)){
     1030                return EOK;
     1031        }
     1032
     1033        path_link = usage_path->link.next;
     1034        while(path_link != &usage_path->link) {
     1035                path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
     1036                usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage);
     1037
     1038                path_link = path_link->next;
     1039        }
     1040
     1041        return EOK;
     1042}
     1043
    7591044
    7601045/**
  • uspace/lib/usb/src/host/device_keeper.c

    r0d92638 ra8ac368  
    4949        assert(instance);
    5050        fibril_mutex_initialize(&instance->guard);
    51         fibril_condvar_initialize(&instance->default_address_occupied);
     51        fibril_condvar_initialize(&instance->change);
    5252        instance->last_address = 0;
    5353        unsigned i = 0;
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
     56                instance->devices[i].control_used = false;
    5657                instance->devices[i].handle = 0;
    5758                instance->devices[i].toggle_status[0] = 0;
     
    7172        fibril_mutex_lock(&instance->guard);
    7273        while (instance->devices[USB_ADDRESS_DEFAULT].occupied) {
    73                 fibril_condvar_wait(&instance->default_address_occupied,
    74                     &instance->guard);
     74                fibril_condvar_wait(&instance->change, &instance->guard);
    7575        }
    7676        instance->devices[USB_ADDRESS_DEFAULT].occupied = true;
     
    9090        instance->devices[USB_ADDRESS_DEFAULT].occupied = false;
    9191        fibril_mutex_unlock(&instance->guard);
    92         fibril_condvar_signal(&instance->default_address_occupied);
     92        fibril_condvar_signal(&instance->change);
    9393}
    9494/*----------------------------------------------------------------------------*/
     
    309309        return instance->devices[address].speed;
    310310}
    311 
     311/*----------------------------------------------------------------------------*/
     312void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     313    usb_address_t address)
     314{
     315        assert(instance);
     316        fibril_mutex_lock(&instance->guard);
     317        while (instance->devices[address].control_used) {
     318                fibril_condvar_wait(&instance->change, &instance->guard);
     319        }
     320        instance->devices[address].control_used = true;
     321        fibril_mutex_unlock(&instance->guard);
     322}
     323/*----------------------------------------------------------------------------*/
     324void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     325    usb_address_t address)
     326{
     327        assert(instance);
     328        fibril_mutex_lock(&instance->guard);
     329        instance->devices[address].control_used = false;
     330        fibril_mutex_unlock(&instance->guard);
     331        fibril_condvar_signal(&instance->change);
     332}
    312333/**
    313334 * @}
  • uspace/srv/hid/kbd/Makefile

    r0d92638 ra8ac368  
    7878                SOURCES += \
    7979                        port/pl050.c \
    80                         ctl/pl050.c
     80                        ctl/pc.c
    8181        endif
    8282endif
  • uspace/srv/hid/kbd/generic/kbd.c

    r0d92638 ra8ac368  
    6767static unsigned lock_keys;
    6868
    69 int cir_service = 0;
    70 int cir_phone = -1;
     69bool irc_service = false;
     70int irc_phone = -1;
    7171
    7272#define NUM_LAYOUTS 3
     
    216216        sysarg_t obio;
    217217       
    218         if ((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc))
    219                 cir_service = SERVICE_FHC;
    220         else if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
    221                 cir_service = SERVICE_OBIO;
    222        
    223         if (cir_service) {
    224                 while (cir_phone < 0)
    225                         cir_phone = service_connect_blocking(cir_service, 0, 0);
     218        if (((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc))
     219            || ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio)))
     220                irc_service = true;
     221       
     222        if (irc_service) {
     223                while (irc_phone < 0)
     224                        irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
    226225        }
    227226       
  • uspace/srv/hid/kbd/include/kbd.h

    r0d92638 ra8ac368  
    3838#define KBD_KBD_H_
    3939
    40 extern int cir_service;
    41 extern int cir_phone;
     40#include <bool.h>
     41
     42extern bool irc_service;
     43extern int irc_phone;
    4244
    4345extern void kbd_push_scancode(int);
  • uspace/srv/hid/kbd/port/ns16550.c

    r0d92638 ra8ac368  
    120120        kbd_push_scancode(scan_code);
    121121       
    122         if (cir_service)
    123                 async_msg_1(cir_phone, IRC_CLEAR_INTERRUPT,
     122        if (irc_service)
     123                async_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
    124124                    IPC_GET_IMETHOD(*call));
    125125}
  • uspace/srv/hid/kbd/port/z8530.c

    r0d92638 ra8ac368  
    108108        kbd_push_scancode(scan_code);
    109109       
    110         if (cir_service)
    111                 async_msg_1(cir_phone, IRC_CLEAR_INTERRUPT,
     110        if (irc_service)
     111                async_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
    112112                    IPC_GET_IMETHOD(*call));
    113113}
  • uspace/srv/hw/irc/apic/apic.c

    r0d92638 ra8ac368  
    5454#define NAME  "apic"
    5555
    56 static bool apic_found = false;
    57 
    5856static int apic_enable_irq(sysarg_t irq)
    5957{
     
    8179                callid = async_get_call(&call);
    8280               
    83                 sysarg_t method = IPC_GET_IMETHOD(call);
    84                 if (method == IPC_M_PHONE_HUNGUP) {
    85                         return;
    86                 }
    87 
    88                 if (!apic_found) {
    89                         async_answer_0(callid, ENOTSUP);
    90                         break;
    91                 }
    92 
    93                 switch (method) {
     81                switch (IPC_GET_IMETHOD(call)) {
    9482                case IRC_ENABLE_INTERRUPT:
    9583                        async_answer_0(callid, apic_enable_irq(IPC_GET_ARG1(call)));
     
    10997 *
    11098 */
    111 static void apic_init(void)
     99static bool apic_init(void)
    112100{
    113101        sysarg_t apic;
    114102       
    115         apic_found = sysinfo_get_value("apic", &apic) && apic;
    116         if (!apic_found) {
    117                 printf(NAME ": Warning: no APIC found\n");
     103        if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
     104                printf(NAME ": No APIC found\n");
     105                return false;
    118106        }
    119107       
    120108        async_set_client_connection(apic_connection);
    121         service_register(SERVICE_APIC);
     109        service_register(SERVICE_IRC);
     110       
     111        return true;
    122112}
    123113
     
    126116        printf(NAME ": HelenOS APIC driver\n");
    127117       
    128         apic_init();
    129 
     118        if (!apic_init())
     119                return -1;
     120       
    130121        printf(NAME ": Accepting connections\n");
    131122        async_manager();
  • uspace/srv/hw/irc/fhc/fhc.c

    r0d92638 ra8ac368  
    136136       
    137137        async_set_client_connection(fhc_connection);
    138         service_register(SERVICE_FHC);
     138        service_register(SERVICE_IRC);
    139139       
    140140        return true;
  • uspace/srv/hw/irc/i8259/i8259.c

    r0d92638 ra8ac368  
    149149       
    150150        async_set_client_connection(i8259_connection);
    151         service_register(SERVICE_I8259);
     151        service_register(SERVICE_IRC);
    152152       
    153153        return true;
  • uspace/srv/hw/irc/obio/obio.c

    r0d92638 ra8ac368  
    137137       
    138138        async_set_client_connection(obio_connection);
    139         service_register(SERVICE_OBIO);
     139        service_register(SERVICE_IRC);
    140140       
    141141        return true;
  • uspace/srv/hw/netif/ne2000/ne2000.c

    r0d92638 ra8ac368  
    7575#define IRQ_GET_TSR(call)  ((int) IPC_GET_ARG3(call))
    7676
    77 static int irc_service = 0;
     77static bool irc_service = false;
    7878static int irc_phone = -1;
    7979
     
    383383        sysarg_t i8259;
    384384       
    385         if ((sysinfo_get_value("apic", &apic) == EOK) && (apic))
    386                 irc_service = SERVICE_APIC;
    387         else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))
    388                 irc_service = SERVICE_I8259;
     385        if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
     386            || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)))
     387                irc_service = true;
    389388       
    390389        if (irc_service) {
    391390                while (irc_phone < 0)
    392                         irc_phone = service_connect_blocking(irc_service, 0, 0);
     391                        irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
    393392        }
    394393       
  • uspace/srv/net/net/net.c

    r0d92638 ra8ac368  
    289289        if (rc != EOK)
    290290                return rc;
     291       
    291292        rc = add_module(NULL, &net_globals.modules, (uint8_t *) NE2000_NAME,
    292293            (uint8_t *) NE2000_FILENAME, SERVICE_NE2000, 0, connect_to_service);
    293294        if (rc != EOK)
    294295                return rc;
     296       
    295297        rc = add_module(NULL, &net_globals.modules, (uint8_t *) ETHERNET_NAME,
    296298            (uint8_t *) ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
    297299        if (rc != EOK)
    298300                return rc;
     301       
    299302        rc = add_module(NULL, &net_globals.modules, (uint8_t *) NILDUMMY_NAME,
    300303            (uint8_t *) NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
     
    590593                rc = start_device(netif);
    591594                if (rc != EOK) {
    592                         printf("%s: Error starting interface %s (%s)\n", NAME,
     595                        printf("%s: Ignoring failed interface %s (%s)\n", NAME,
    593596                            netif->name, str_error(rc));
    594597                        measured_strings_destroy(&netif->configuration);
    595598                        netifs_exclude_index(&net_globals.netifs, index);
    596                        
    597                         return rc;
     599                        continue;
    598600                }
    599601               
  • uspace/srv/vfs/vfs_ops.c

    r0d92638 ra8ac368  
    12341234        if (!parentc) {
    12351235                fibril_rwlock_write_unlock(&namespace_rwlock);
     1236                vfs_node_put(old_node);
    12361237                async_answer_0(rid, rc);
    12371238                free(old);
     
    12511252        if (rc != EOK) {
    12521253                fibril_rwlock_write_unlock(&namespace_rwlock);
     1254                vfs_node_put(old_node);
    12531255                async_answer_0(rid, rc);
    12541256                free(old);
     
    12611263            (old_node->devmap_handle != new_par_lr.triplet.devmap_handle)) {
    12621264                fibril_rwlock_write_unlock(&namespace_rwlock);
     1265                vfs_node_put(old_node);
    12631266                async_answer_0(rid, EXDEV);     /* different file systems */
    12641267                free(old);
     
    12791282                if (!new_node) {
    12801283                        fibril_rwlock_write_unlock(&namespace_rwlock);
     1284                        vfs_node_put(old_node);
    12811285                        async_answer_0(rid, ENOMEM);
    12821286                        free(old);
     
    12901294        default:
    12911295                fibril_rwlock_write_unlock(&namespace_rwlock);
     1296                vfs_node_put(old_node);
    12921297                async_answer_0(rid, ENOTEMPTY);
    12931298                free(old);
     
    13001305        if (rc != EOK) {
    13011306                fibril_rwlock_write_unlock(&namespace_rwlock);
     1307                vfs_node_put(old_node);
    13021308                if (new_node)
    13031309                        vfs_node_put(new_node);
Note: See TracChangeset for help on using the changeset viewer.