Changes in / [d8421c4:f97717d9] in mainline


Ignore:
Files:
23 added
25 deleted
36 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    rd8421c4 rf97717d9  
    99_link.ld
    1010./*.iso
     11
     12./tools/__pycache__/
    1113
    1214./Makefile.common
     
    139141.cproject
    140142.project
     143.settings
     144.pydevproject
     145
  • HelenOS.config

    rd8421c4 rf97717d9  
    552552! CONFIG_RUN_VIRTUAL_USB_HC (n/y)
    553553
     554% Polling UHCI & OHCI (no interrupts)
     555! [PLATFORM=ia32|PLATFORM=amd64] CONFIG_USBHC_NO_INTERRUPTS (y/n)
  • boot/arch/amd64/Makefile.inc

    rd8421c4 rf97717d9  
    4949        usbflbk \
    5050        usbhub \
    51         usbhid \
     51        usbkbd \
    5252        usbmid \
    5353        usbmouse \
  • uspace/Makefile

    rd8421c4 rf97717d9  
    122122                drv/uhci-rhd \
    123123                drv/usbflbk \
    124                 drv/usbhid \
     124                drv/usbkbd \
    125125                drv/usbhub \
    126126                drv/usbmid \
     
    142142                drv/uhci-rhd \
    143143                drv/usbflbk \
    144                 drv/usbhid \
     144                drv/usbkbd \
    145145                drv/usbhub \
    146146                drv/usbmid \
  • uspace/app/usbinfo/info.c

    rd8421c4 rf97717d9  
    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

    rd8421c4 rf97717d9  
    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

    rd8421c4 rf97717d9  
    8484void dump_descriptor_tree_full(usbinfo_device_t *);
    8585void dump_strings(usbinfo_device_t *);
     86void dump_status(usbinfo_device_t *);
    8687
    8788
  • uspace/drv/ehci-hcd/main.c

    rd8421c4 rf97717d9  
    119119int main(int argc, char *argv[])
    120120{
    121         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     121        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    122122        return ddf_driver_main(&ehci_driver);
    123123}
  • uspace/drv/ohci/batch.c

    rd8421c4 rf97717d9  
    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/iface.c

    rd8421c4 rf97717d9  
    3333 */
    3434#include <ddf/driver.h>
    35 #include <ddf/interrupt.h>
    36 #include <device/hw_res.h>
    3735#include <errno.h>
    38 #include <str_error.h>
    39 
    40 #include <usb_iface.h>
    41 #include <usb/ddfiface.h>
     36
    4237#include <usb/debug.h>
    4338
     
    6055static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
    6156{
    62   assert(fun);
    63   hc_t *hc = fun_to_hc(fun);
    64   assert(hc);
    65   usb_log_debug("Default address request with speed %d.\n", speed);
    66   usb_device_keeper_reserve_default_address(&hc->manager, speed);
    67   return EOK;
     57        assert(fun);
     58        hc_t *hc = fun_to_hc(fun);
     59        assert(hc);
     60        usb_log_debug("Default address request with speed %d.\n", speed);
     61        usb_device_keeper_reserve_default_address(&hc->manager, speed);
     62        return EOK;
    6863}
    6964/*----------------------------------------------------------------------------*/
     
    7570static int release_default_address(ddf_fun_t *fun)
    7671{
    77   assert(fun);
    78   hc_t *hc = fun_to_hc(fun);
    79   assert(hc);
    80   usb_log_debug("Default address release.\n");
    81   usb_device_keeper_release_default_address(&hc->manager);
    82   return EOK;
     72        assert(fun);
     73        hc_t *hc = fun_to_hc(fun);
     74        assert(hc);
     75        usb_log_debug("Default address release.\n");
     76        usb_device_keeper_release_default_address(&hc->manager);
     77        return EOK;
    8378}
    8479/*----------------------------------------------------------------------------*/
     
    9085 * @return Error code.
    9186 */
    92 static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    93     usb_address_t *address)
    94 {
    95   assert(fun);
    96   hc_t *hc = fun_to_hc(fun);
    97   assert(hc);
    98   assert(address);
    99 
    100   usb_log_debug("Address request with speed %d.\n", speed);
    101   *address = device_keeper_get_free_address(&hc->manager, speed);
    102   usb_log_debug("Address request with result: %d.\n", *address);
    103   if (*address <= 0)
    104     return *address;
    105   return EOK;
     87static int request_address(
     88    ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address)
     89{
     90        assert(fun);
     91        hc_t *hc = fun_to_hc(fun);
     92        assert(hc);
     93        assert(address);
     94
     95        usb_log_debug("Address request with speed %d.\n", speed);
     96        *address = device_keeper_get_free_address(&hc->manager, speed);
     97        usb_log_debug("Address request with result: %d.\n", *address);
     98        if (*address <= 0)
     99                return *address;
     100        return EOK;
    106101}
    107102/*----------------------------------------------------------------------------*/
     
    113108 * @return Error code.
    114109 */
    115 static int bind_address(ddf_fun_t *fun,
    116     usb_address_t address, devman_handle_t handle)
    117 {
    118   assert(fun);
    119   hc_t *hc = fun_to_hc(fun);
    120   assert(hc);
    121   usb_log_debug("Address bind %d-%d.\n", address, handle);
    122   usb_device_keeper_bind(&hc->manager, address, handle);
    123   return EOK;
     110static int bind_address(
     111    ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     112{
     113        assert(fun);
     114        hc_t *hc = fun_to_hc(fun);
     115        assert(hc);
     116        usb_log_debug("Address bind %d-%d.\n", address, handle);
     117        usb_device_keeper_bind(&hc->manager, address, handle);
     118        return EOK;
    124119}
    125120/*----------------------------------------------------------------------------*/
     
    132127static int release_address(ddf_fun_t *fun, usb_address_t address)
    133128{
    134   assert(fun);
    135   hc_t *hc = fun_to_hc(fun);
    136   assert(hc);
    137   usb_log_debug("Address release %d.\n", address);
    138   usb_device_keeper_release(&hc->manager, address);
    139   return EOK;
    140 }
    141 
     129        assert(fun);
     130        hc_t *hc = fun_to_hc(fun);
     131        assert(hc);
     132        usb_log_debug("Address release %d.\n", address);
     133        usb_device_keeper_release(&hc->manager, address);
     134        return EOK;
     135}
     136/*----------------------------------------------------------------------------*/
    142137/** Register endpoint for bandwidth reservation.
    143138 *
     
    151146 * @return Error code.
    152147 */
    153 static int register_endpoint(ddf_fun_t *fun,
    154     usb_address_t address, usb_endpoint_t endpoint,
     148static int register_endpoint(
     149    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
    155150    usb_transfer_type_t transfer_type, usb_direction_t direction,
    156151    size_t max_packet_size, unsigned int interval)
     
    160155        return ENOTSUP;
    161156}
    162 
     157/*----------------------------------------------------------------------------*/
    163158/** Unregister endpoint (free some bandwidth reservation).
    164159 *
     
    169164 * @return Error code.
    170165 */
    171 static int unregister_endpoint(ddf_fun_t *fun, usb_address_t address,
     166static int unregister_endpoint(
     167    ddf_fun_t *fun, usb_address_t address,
    172168    usb_endpoint_t endpoint, usb_direction_t direction)
    173169{
     
    194190 * @return Error code.
    195191 */
    196 static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    197     size_t max_packet_size, void *data, size_t size,
    198     usbhc_iface_transfer_out_callback_t callback, void *arg)
    199 {
    200   hc_t *hc = fun_to_hc(fun);
    201   assert(hc);
    202   usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address);
    203 
    204   usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
    205       target.address, target.endpoint, size, max_packet_size);
    206 
    207   usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    208       max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
    209       &hc->manager);
    210   if (!batch)
    211     return ENOMEM;
    212   batch_interrupt_out(batch);
    213   const int ret = hc_schedule(hc, batch);
    214   if (ret != EOK) {
    215     batch_dispose(batch);
    216     return ret;
    217   }
    218   return EOK;
     192static int interrupt_out(
     193    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     194    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
     195{
     196        assert(fun);
     197        hc_t *hc = fun_to_hc(fun);
     198        assert(hc);
     199        usb_speed_t speed =
     200            usb_device_keeper_get_speed(&hc->manager, target.address);
     201
     202        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
     203            target.address, target.endpoint, size, max_packet_size);
     204
     205        usb_transfer_batch_t *batch =
     206            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     207                speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     208        if (!batch)
     209                return ENOMEM;
     210        batch_interrupt_out(batch);
     211        const int ret = hc_schedule(hc, batch);
     212        if (ret != EOK) {
     213                batch_dispose(batch);
     214        }
     215        return ret;
    219216}
    220217/*----------------------------------------------------------------------------*/
     
    236233 * @return Error code.
    237234 */
    238 static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    239     size_t max_packet_size, void *data, size_t size,
    240     usbhc_iface_transfer_in_callback_t callback, void *arg)
    241 {
    242   assert(fun);
    243   hc_t *hc = fun_to_hc(fun);
    244   assert(hc);
    245   usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address);
    246   usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
    247       target.address, target.endpoint, size, max_packet_size);
    248 
    249   usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    250       max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
    251       &hc->manager);
    252   if (!batch)
    253     return ENOMEM;
    254   batch_interrupt_in(batch);
    255   const int ret = hc_schedule(hc, batch);
    256   if (ret != EOK) {
    257     batch_dispose(batch);
    258     return ret;
    259   }
    260   return EOK;
     235static int interrupt_in(
     236    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     237    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
     238{
     239        assert(fun);
     240        hc_t *hc = fun_to_hc(fun);
     241        assert(hc);
     242        usb_speed_t speed =
     243            usb_device_keeper_get_speed(&hc->manager, target.address);
     244        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
     245            target.address, target.endpoint, size, max_packet_size);
     246
     247        usb_transfer_batch_t *batch =
     248            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     249                speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     250        if (!batch)
     251                return ENOMEM;
     252        batch_interrupt_in(batch);
     253        const int ret = hc_schedule(hc, batch);
     254        if (ret != EOK) {
     255                batch_dispose(batch);
     256        }
     257        return ret;
    261258}
    262259/*----------------------------------------------------------------------------*/
     
    278275 * @return Error code.
    279276 */
    280 static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    281     size_t max_packet_size, void *data, size_t size,
    282     usbhc_iface_transfer_out_callback_t callback, void *arg)
    283 {
    284   assert(fun);
    285   hc_t *hc = fun_to_hc(fun);
    286   assert(hc);
    287   usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address);
    288 
    289   usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
    290       target.address, target.endpoint, size, max_packet_size);
    291 
    292   usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    293       max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
    294       &hc->manager);
    295   if (!batch)
    296     return ENOMEM;
    297   batch_bulk_out(batch);
    298   const int ret = hc_schedule(hc, batch);
    299   if (ret != EOK) {
    300     batch_dispose(batch);
    301     return ret;
    302   }
    303   return EOK;
    304 
     277static int bulk_out(
     278    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     279    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
     280{
     281        assert(fun);
     282        hc_t *hc = fun_to_hc(fun);
     283        assert(hc);
     284        usb_speed_t speed =
     285            usb_device_keeper_get_speed(&hc->manager, target.address);
     286
     287        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
     288            target.address, target.endpoint, size, max_packet_size);
     289
     290        usb_transfer_batch_t *batch =
     291            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     292                data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     293        if (!batch)
     294                return ENOMEM;
     295        batch_bulk_out(batch);
     296        const int ret = hc_schedule(hc, batch);
     297        if (ret != EOK) {
     298                batch_dispose(batch);
     299        }
     300        return ret;
    305301}
    306302/*----------------------------------------------------------------------------*/
     
    322318 * @return Error code.
    323319 */
    324 static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    325     size_t max_packet_size, void *data, size_t size,
    326     usbhc_iface_transfer_in_callback_t callback, void *arg)
    327 {
    328   assert(fun);
    329   hc_t *hc = fun_to_hc(fun);
    330   assert(hc);
    331   usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address);
    332   usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
    333       target.address, target.endpoint, size, max_packet_size);
    334 
    335   usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    336       max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
    337       &hc->manager);
    338   if (!batch)
    339     return ENOMEM;
    340   batch_bulk_in(batch);
    341   const int ret = hc_schedule(hc, batch);
    342   if (ret != EOK) {
    343     batch_dispose(batch);
    344     return ret;
    345   }
    346   return EOK;
     320static int bulk_in(
     321    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     322    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
     323{
     324        assert(fun);
     325        hc_t *hc = fun_to_hc(fun);
     326        assert(hc);
     327        usb_speed_t speed =
     328            usb_device_keeper_get_speed(&hc->manager, target.address);
     329        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
     330            target.address, target.endpoint, size, max_packet_size);
     331
     332        usb_transfer_batch_t *batch =
     333            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     334                data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     335        if (!batch)
     336                return ENOMEM;
     337        batch_bulk_in(batch);
     338        const int ret = hc_schedule(hc, batch);
     339        if (ret != EOK) {
     340                batch_dispose(batch);
     341        }
     342        return ret;
    347343}
    348344/*----------------------------------------------------------------------------*/
     
    367363 * @return Error code.
    368364 */
    369 static int control_write(ddf_fun_t *fun, usb_target_t target,
    370     size_t max_packet_size,
    371     void *setup_data, size_t setup_size,
    372     void *data, size_t size,
     365static int control_write(
     366    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     367    void *setup_data, size_t setup_size, void *data, size_t size,
    373368    usbhc_iface_transfer_out_callback_t callback, void *arg)
    374369{
    375   assert(fun);
    376   hc_t *hc = fun_to_hc(fun);
    377   assert(hc);
    378   usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address);
    379   usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
    380       speed, target.address, target.endpoint, size, max_packet_size);
    381 
    382   if (setup_size != 8)
    383     return EINVAL;
    384 
    385   usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    386       max_packet_size, speed, data, size, setup_data, setup_size,
    387       NULL, callback, arg, &hc->manager);
    388   if (!batch)
    389     return ENOMEM;
    390   usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    391   batch_control_write(batch);
    392   const int ret = hc_schedule(hc, batch);
    393   if (ret != EOK) {
    394     batch_dispose(batch);
    395     return ret;
    396   }
    397   return EOK;
     370        assert(fun);
     371        hc_t *hc = fun_to_hc(fun);
     372        assert(hc);
     373        usb_speed_t speed =
     374            usb_device_keeper_get_speed(&hc->manager, target.address);
     375        usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
     376            speed, target.address, target.endpoint, size, max_packet_size);
     377
     378        if (setup_size != 8)
     379                return EINVAL;
     380
     381        usb_transfer_batch_t *batch =
     382            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     383                speed, data, size, setup_data, setup_size, NULL, callback, arg,
     384                &hc->manager);
     385        if (!batch)
     386                return ENOMEM;
     387        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
     388        batch_control_write(batch);
     389        const int ret = hc_schedule(hc, batch);
     390        if (ret != EOK) {
     391                batch_dispose(batch);
     392        }
     393        return ret;
    398394}
    399395/*----------------------------------------------------------------------------*/
     
    418414 * @return Error code.
    419415 */
    420 static int control_read(ddf_fun_t *fun, usb_target_t target,
    421     size_t max_packet_size,
    422     void *setup_data, size_t setup_size,
    423     void *data, size_t size,
     416static int control_read(
     417    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     418    void *setup_data, size_t setup_size, void *data, size_t size,
    424419    usbhc_iface_transfer_in_callback_t callback, void *arg)
    425420{
    426   assert(fun);
    427   hc_t *hc = fun_to_hc(fun);
    428   assert(hc);
    429   usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address);
    430 
    431   usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
    432       speed, target.address, target.endpoint, size, max_packet_size);
    433   usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    434       max_packet_size, speed, data, size, setup_data, setup_size, callback,
    435       NULL, arg, &hc->manager);
    436   if (!batch)
    437     return ENOMEM;
    438   batch_control_read(batch);
    439   const int ret = hc_schedule(hc, batch);
    440   if (ret != EOK) {
    441     batch_dispose(batch);
    442     return ret;
    443   }
    444   return EOK;
     421        assert(fun);
     422        hc_t *hc = fun_to_hc(fun);
     423        assert(hc);
     424        usb_speed_t speed =
     425            usb_device_keeper_get_speed(&hc->manager, target.address);
     426
     427        usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
     428            speed, target.address, target.endpoint, size, max_packet_size);
     429        usb_transfer_batch_t *batch =
     430            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     431                speed, data, size, setup_data, setup_size, callback, NULL, arg,
     432                &hc->manager);
     433        if (!batch)
     434                return ENOMEM;
     435        batch_control_read(batch);
     436        const int ret = hc_schedule(hc, batch);
     437        if (ret != EOK) {
     438                batch_dispose(batch);
     439        }
     440        return ret;
    445441}
    446442/*----------------------------------------------------------------------------*/
     
    463459
    464460        .control_write = control_write,
    465         .control_read = control_read
     461        .control_read = control_read,
    466462};
    467463
  • uspace/drv/ohci/main.c

    rd8421c4 rf97717d9  
    149149        }
    150150
     151
    151152        bool interrupts = false;
     153#ifdef CONFIG_USBHC_NO_INTERRUPTS
     154        usb_log_warning("Interrupts disabled in OS config, " \
     155            "falling back to polling.\n");
     156#else
    152157        ret = pci_enable_interrupts(device);
    153158        if (ret != EOK) {
    154                 usb_log_warning(
    155                     "Failed(%d) to enable interrupts, fall back to polling.\n",
    156                     ret);
     159                usb_log_warning("Failed to enable interrupts: %s.\n",
     160                    str_error(ret));
     161                usb_log_info("HW interrupts not available, " \
     162                    "falling back to polling.\n");
    157163        } else {
    158164                usb_log_debug("Hw interrupts enabled.\n");
    159165                interrupts = true;
    160166        }
     167#endif
    161168
    162169        ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts);
     
    199206int main(int argc, char *argv[])
    200207{
    201         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     208        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    202209        sleep(5);
    203210        return ddf_driver_main(&ohci_driver);
  • uspace/drv/uhci-hcd/Makefile

    rd8421c4 rf97717d9  
    3737        transfer_list.c \
    3838        uhci.c \
    39         uhci_hc.c \
    40         uhci_rh.c \
    41         uhci_struct/transfer_descriptor.c \
     39        hc.c \
     40        root_hub.c \
     41        hw_struct/transfer_descriptor.c \
    4242        pci.c \
    4343        batch.c
  • uspace/drv/uhci-hcd/batch.c

    rd8421c4 rf97717d9  
    4040#include "batch.h"
    4141#include "transfer_list.h"
    42 #include "uhci_hc.h"
     42#include "hw_struct/transfer_descriptor.h"
    4343#include "utils/malloc32.h"
    44 #include "uhci_struct/transfer_descriptor.h"
    4544
    4645#define DEFAULT_ERROR_COUNT 3
     
    4948        qh_t *qh;
    5049        td_t *tds;
    51         size_t packets;
     50        size_t transfers;
    5251        usb_device_keeper_t *manager;
    5352} uhci_batch_t;
     
    6564 * @param[in] target Device and endpoint target of the transaction.
    6665 * @param[in] transfer_type Interrupt, Control or Bulk.
    67  * @param[in] max_packet_size maximum allowed size of data packets.
     66 * @param[in] max_packet_size maximum allowed size of data transfers.
    6867 * @param[in] speed Speed of the transaction.
    6968 * @param[in] buffer Data source/destination.
     
    7877 * NULL otherwise.
    7978 *
    80  * Determines the number of needed packets (TDs). Prepares a transport buffer
     79 * Determines the number of needed transfers (TDs). Prepares a transport buffer
    8180 * (that is accessible by the hardware). Initializes parameters needed for the
    8281 * transaction and callback.
     
    118117        instance->private_data = data;
    119118
    120         data->packets = (buffer_size + max_packet_size - 1) / max_packet_size;
     119        data->transfers = (buffer_size + max_packet_size - 1) / max_packet_size;
    121120        if (transfer_type == USB_TRANSFER_CONTROL) {
    122                 data->packets += 2;
    123         }
    124 
    125         data->tds = malloc32(sizeof(td_t) * data->packets);
     121                data->transfers += 2;
     122        }
     123
     124        data->tds = malloc32(sizeof(td_t) * data->transfers);
    126125        CHECK_NULL_DISPOSE_RETURN(
    127126            data->tds, "Failed to allocate transfer descriptors.\n");
    128         bzero(data->tds, sizeof(td_t) * data->packets);
     127        bzero(data->tds, sizeof(td_t) * data->transfers);
    129128
    130129        data->qh = malloc32(sizeof(qh_t));
     
    167166        assert(data);
    168167
    169         usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",
    170             instance, data->packets);
     168        usb_log_debug2("Batch(%p) checking %d transfer(s) for completion.\n",
     169            instance, data->transfers);
    171170        instance->transfered_size = 0;
    172171        size_t i = 0;
    173         for (;i < data->packets; ++i) {
     172        for (;i < data->transfers; ++i) {
    174173                if (td_is_active(&data->tds[i])) {
    175174                        return false;
     
    299298 *
    300299 * @param[in] instance Batch structure to use.
    301  * @param[in] pid to use for data packets.
     300 * @param[in] pid Pid to use for data transfers.
    302301 *
    303302 * Packets with alternating toggle bit and supplied pid value.
    304  * The last packet is marked with IOC flag.
     303 * The last transfer is marked with IOC flag.
    305304 */
    306305void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
     
    315314        assert(toggle == 0 || toggle == 1);
    316315
    317         size_t packet = 0;
     316        size_t transfer = 0;
    318317        size_t remain_size = instance->buffer_size;
    319318        while (remain_size > 0) {
     
    326325                    remain_size : instance->max_packet_size;
    327326
    328                 td_t *next_packet = (packet + 1 < data->packets)
    329                     ? &data->tds[packet + 1] : NULL;
    330 
    331                 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);
    332331                assert(packet_size <= remain_size);
    333332
    334333                td_init(
    335                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     334                    &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
    336335                    toggle, false, low_speed, instance->target, pid, trans_data,
    337                     next_packet);
     336                    next_transfer);
    338337
    339338
    340339                toggle = 1 - toggle;
    341340                remain_size -= packet_size;
    342                 ++packet;
    343         }
    344         td_set_ioc(&data->tds[packet - 1]);
     341                ++transfer;
     342        }
     343        td_set_ioc(&data->tds[transfer - 1]);
    345344        usb_device_keeper_set_toggle(data->manager, instance->target,
    346345            instance->direction, toggle);
     
    350349 *
    351350 * @param[in] instance Batch structure to use.
    352  * @param[in] data_stage to use for data packets.
    353  * @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.
    354353 *
    355354 * Setup stage with toggle 0 and USB_PID_SETUP.
    356355 * Data stage with alternating toggle and pid supplied by parameter.
    357356 * Status stage with toggle 1 and pid supplied by parameter.
    358  * The last packet is marked with IOC.
     357 * The last transfer is marked with IOC.
    359358 */
    360359void batch_control(usb_transfer_batch_t *instance,
     
    364363        uhci_batch_t *data = instance->private_data;
    365364        assert(data);
    366         assert(data->packets >= 2);
     365        assert(data->transfers >= 2);
    367366
    368367        const bool low_speed = instance->speed == USB_SPEED_LOW;
     
    375374
    376375        /* data stage */
    377         size_t packet = 1;
     376        size_t transfer = 1;
    378377        size_t remain_size = instance->buffer_size;
    379378        while (remain_size > 0) {
     
    389388
    390389                td_init(
    391                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     390                    &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
    392391                    toggle, false, low_speed, instance->target, data_stage,
    393                     control_data, &data->tds[packet + 1]);
    394 
    395                 ++packet;
    396                 assert(packet < data->packets);
     392                    control_data, &data->tds[transfer + 1]);
     393
     394                ++transfer;
     395                assert(transfer < data->transfers);
    397396                assert(packet_size <= remain_size);
    398397                remain_size -= packet_size;
     
    400399
    401400        /* status stage */
    402         assert(packet == data->packets - 1);
     401        assert(transfer == data->transfers - 1);
    403402
    404403        td_init(
    405             &data->tds[packet], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
     404            &data->tds[transfer], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
    406405            instance->target, status_stage, NULL, NULL);
    407         td_set_ioc(&data->tds[packet]);
     406        td_set_ioc(&data->tds[transfer]);
    408407
    409408        usb_log_debug2("Control last TD status: %x.\n",
    410             data->tds[packet].status);
     409            data->tds[transfer].status);
    411410}
    412411/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/batch.h

    rd8421c4 rf97717d9  
    4242#include <usb/host/batch.h>
    4343
    44 #include "uhci_struct/queue_head.h"
     44#include "hw_struct/queue_head.h"
    4545
    4646usb_transfer_batch_t * batch_get(
  • uspace/drv/uhci-hcd/iface.c

    rd8421c4 rf97717d9  
    3333 */
    3434#include <ddf/driver.h>
    35 #include <remote_usbhc.h>
     35#include <errno.h>
    3636
    3737#include <usb/debug.h>
    3838
    39 #include <errno.h>
    40 
    4139#include "iface.h"
    42 #include "uhci_hc.h"
     40#include "hc.h"
    4341
    4442/** Reserve default address interface function
     
    4846 * @return Error code.
    4947 */
    50 /*----------------------------------------------------------------------------*/
    5148static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
    5249{
    5350        assert(fun);
    54         uhci_hc_t *hc = fun_to_uhci_hc(fun);
     51        hc_t *hc = fun_to_hc(fun);
    5552        assert(hc);
    5653        usb_log_debug("Default address request with speed %d.\n", speed);
    57         usb_device_keeper_reserve_default_address(&hc->device_manager, speed);
     54        usb_device_keeper_reserve_default_address(&hc->manager, speed);
    5855        return EOK;
    5956}
     
    6764{
    6865        assert(fun);
    69         uhci_hc_t *hc = fun_to_uhci_hc(fun);
     66        hc_t *hc = fun_to_hc(fun);
    7067        assert(hc);
    7168        usb_log_debug("Default address release.\n");
    72         usb_device_keeper_release_default_address(&hc->device_manager);
     69        usb_device_keeper_release_default_address(&hc->manager);
    7370        return EOK;
    7471}
     
    8178 * @return Error code.
    8279 */
    83 static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    84     usb_address_t *address)
    85 {
    86         assert(fun);
    87         uhci_hc_t *hc = fun_to_uhci_hc(fun);
     80static int request_address(
     81    ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address)
     82{
     83        assert(fun);
     84        hc_t *hc = fun_to_hc(fun);
    8885        assert(hc);
    8986        assert(address);
    9087
    9188        usb_log_debug("Address request with speed %d.\n", speed);
    92         *address = device_keeper_get_free_address(&hc->device_manager, speed);
     89        *address = device_keeper_get_free_address(&hc->manager, speed);
    9390        usb_log_debug("Address request with result: %d.\n", *address);
    9491        if (*address <= 0)
    95           return *address;
     92                return *address;
    9693        return EOK;
    9794}
     
    108105{
    109106        assert(fun);
    110         uhci_hc_t *hc = fun_to_uhci_hc(fun);
     107        hc_t *hc = fun_to_hc(fun);
    111108        assert(hc);
    112109        usb_log_debug("Address bind %d-%d.\n", address, handle);
    113         usb_device_keeper_bind(&hc->device_manager, address, handle);
     110        usb_device_keeper_bind(&hc->manager, address, handle);
    114111        return EOK;
    115112}
     
    124121{
    125122        assert(fun);
    126         uhci_hc_t *hc = fun_to_uhci_hc(fun);
     123        hc_t *hc = fun_to_hc(fun);
    127124        assert(hc);
    128125        usb_log_debug("Address release %d.\n", address);
    129         usb_device_keeper_release(&hc->device_manager, address);
     126        usb_device_keeper_release(&hc->manager, address);
    130127        return EOK;
    131128}
     
    142139 * @return Error code.
    143140 */
    144 static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    145     size_t max_packet_size, void *data, size_t size,
    146     usbhc_iface_transfer_out_callback_t callback, void *arg)
    147 {
    148         assert(fun);
    149         uhci_hc_t *hc = fun_to_uhci_hc(fun);
    150         assert(hc);
    151         usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address);
     141static int interrupt_out(
     142    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     143    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
     144{
     145        assert(fun);
     146        hc_t *hc = fun_to_hc(fun);
     147        assert(hc);
     148        usb_speed_t speed =
     149            usb_device_keeper_get_speed(&hc->manager, target.address);
    152150
    153151        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
    154152            target.address, target.endpoint, size, max_packet_size);
    155153
    156         usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    157             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
    158             &hc->device_manager);
     154        usb_transfer_batch_t *batch =
     155            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     156                speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);
    159157        if (!batch)
    160158                return ENOMEM;
    161159        batch_interrupt_out(batch);
    162         const int ret = uhci_hc_schedule(hc, batch);
    163         if (ret != EOK) {
    164                 batch_dispose(batch);
    165                 return ret;
    166         }
    167         return EOK;
     160        const int ret = hc_schedule(hc, batch);
     161        if (ret != EOK) {
     162                batch_dispose(batch);
     163        }
     164        return ret;
    168165}
    169166/*----------------------------------------------------------------------------*/
     
    179176 * @return Error code.
    180177 */
    181 static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    182     size_t max_packet_size, void *data, size_t size,
    183     usbhc_iface_transfer_in_callback_t callback, void *arg)
    184 {
    185         assert(fun);
    186         uhci_hc_t *hc = fun_to_uhci_hc(fun);
    187         assert(hc);
    188         usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address);
     178static int interrupt_in(
     179    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     180    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
     181{
     182        assert(fun);
     183        hc_t *hc = fun_to_hc(fun);
     184        assert(hc);
     185        usb_speed_t speed =
     186            usb_device_keeper_get_speed(&hc->manager, target.address);
    189187        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
    190188            target.address, target.endpoint, size, max_packet_size);
    191189
    192         usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    193             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
    194                         &hc->device_manager);
     190        usb_transfer_batch_t *batch =
     191            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     192                speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);
    195193        if (!batch)
    196194                return ENOMEM;
    197195        batch_interrupt_in(batch);
    198         const int ret = uhci_hc_schedule(hc, batch);
    199         if (ret != EOK) {
    200                 batch_dispose(batch);
    201                 return ret;
    202         }
    203         return EOK;
     196        const int ret = hc_schedule(hc, batch);
     197        if (ret != EOK) {
     198                batch_dispose(batch);
     199        }
     200        return ret;
    204201}
    205202/*----------------------------------------------------------------------------*/
     
    215212 * @return Error code.
    216213 */
    217 static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    218     size_t max_packet_size, void *data, size_t size,
    219     usbhc_iface_transfer_out_callback_t callback, void *arg)
    220 {
    221         assert(fun);
    222         uhci_hc_t *hc = fun_to_uhci_hc(fun);
    223         assert(hc);
    224         usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address);
     214static int bulk_out(
     215    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     216    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
     217{
     218        assert(fun);
     219        hc_t *hc = fun_to_hc(fun);
     220        assert(hc);
     221        usb_speed_t speed =
     222            usb_device_keeper_get_speed(&hc->manager, target.address);
    225223
    226224        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
    227225            target.address, target.endpoint, size, max_packet_size);
    228226
    229         usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    230             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
    231             &hc->device_manager);
     227        usb_transfer_batch_t *batch =
     228            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     229                data, size, NULL, 0, NULL, callback, arg, &hc->manager);
    232230        if (!batch)
    233231                return ENOMEM;
    234232        batch_bulk_out(batch);
    235         const int ret = uhci_hc_schedule(hc, batch);
    236         if (ret != EOK) {
    237                 batch_dispose(batch);
    238                 return ret;
    239         }
    240         return EOK;
     233        const int ret = hc_schedule(hc, batch);
     234        if (ret != EOK) {
     235                batch_dispose(batch);
     236        }
     237        return ret;
    241238}
    242239/*----------------------------------------------------------------------------*/
     
    252249 * @return Error code.
    253250 */
    254 static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    255     size_t max_packet_size, void *data, size_t size,
    256     usbhc_iface_transfer_in_callback_t callback, void *arg)
    257 {
    258         assert(fun);
    259         uhci_hc_t *hc = fun_to_uhci_hc(fun);
    260         assert(hc);
    261         usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address);
     251static int bulk_in(
     252    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     253    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
     254{
     255        assert(fun);
     256        hc_t *hc = fun_to_hc(fun);
     257        assert(hc);
     258        usb_speed_t speed =
     259            usb_device_keeper_get_speed(&hc->manager, target.address);
    262260        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
    263261            target.address, target.endpoint, size, max_packet_size);
    264262
    265         usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    266             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
    267             &hc->device_manager);
     263        usb_transfer_batch_t *batch =
     264            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     265                data, size, NULL, 0, callback, NULL, arg, &hc->manager);
    268266        if (!batch)
    269267                return ENOMEM;
    270268        batch_bulk_in(batch);
    271         const int ret = uhci_hc_schedule(hc, batch);
    272         if (ret != EOK) {
    273                 batch_dispose(batch);
    274                 return ret;
    275         }
    276         return EOK;
     269        const int ret = hc_schedule(hc, batch);
     270        if (ret != EOK) {
     271                batch_dispose(batch);
     272        }
     273        return ret;
    277274}
    278275/*----------------------------------------------------------------------------*/
     
    282279 * @param[in] target USB device to write to.
    283280 * @param[in] max_packet_size maximum size of data packet the device accepts.
    284  * @param[in] setup_data Data to send with SETUP packet.
    285  * @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).
    286283 * @param[in] data Source of data.
    287284 * @param[in] size Size of data source.
     
    290287 * @return Error code.
    291288 */
    292 static int control_write(ddf_fun_t *fun, usb_target_t target,
    293     size_t max_packet_size,
     289static int control_write(
     290    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    294291    void *setup_data, size_t setup_size, void *data, size_t size,
    295292    usbhc_iface_transfer_out_callback_t callback, void *arg)
    296293{
    297294        assert(fun);
    298         uhci_hc_t *hc = fun_to_uhci_hc(fun);
    299         assert(hc);
    300         usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address);
     295        hc_t *hc = fun_to_hc(fun);
     296        assert(hc);
     297        usb_speed_t speed =
     298            usb_device_keeper_get_speed(&hc->manager, target.address);
    301299        usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
    302300            speed, target.address, target.endpoint, size, max_packet_size);
     
    305303                return EINVAL;
    306304
    307         usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    308             max_packet_size, speed, data, size, setup_data, setup_size,
    309             NULL, callback, arg, &hc->device_manager);
    310         if (!batch)
    311                 return ENOMEM;
    312         usb_device_keeper_reset_if_need(&hc->device_manager, target, setup_data);
     305        usb_transfer_batch_t *batch =
     306            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
     307                data, size, setup_data, setup_size, NULL, callback, arg,
     308                &hc->manager);
     309        if (!batch)
     310                return ENOMEM;
     311        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    313312        batch_control_write(batch);
    314         const int ret = uhci_hc_schedule(hc, batch);
    315         if (ret != EOK) {
    316                 batch_dispose(batch);
    317                 return ret;
    318         }
    319         return EOK;
     313        const int ret = hc_schedule(hc, batch);
     314        if (ret != EOK) {
     315                batch_dispose(batch);
     316        }
     317        return ret;
    320318}
    321319/*----------------------------------------------------------------------------*/
     
    333331 * @return Error code.
    334332 */
    335 static int control_read(ddf_fun_t *fun, usb_target_t target,
    336     size_t max_packet_size,
     333static int control_read(
     334    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    337335    void *setup_data, size_t setup_size, void *data, size_t size,
    338336    usbhc_iface_transfer_in_callback_t callback, void *arg)
    339337{
    340338        assert(fun);
    341         uhci_hc_t *hc = fun_to_uhci_hc(fun);
    342         assert(hc);
    343         usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address);
     339        hc_t *hc = fun_to_hc(fun);
     340        assert(hc);
     341        usb_speed_t speed =
     342            usb_device_keeper_get_speed(&hc->manager, target.address);
    344343
    345344        usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
    346345            speed, target.address, target.endpoint, size, max_packet_size);
    347         usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    348             max_packet_size, speed, data, size, setup_data, setup_size, callback,
    349             NULL, arg, &hc->device_manager);
     346        usb_transfer_batch_t *batch =
     347            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
     348                data, size, setup_data, setup_size, callback, NULL, arg,
     349                &hc->manager);
    350350        if (!batch)
    351351                return ENOMEM;
    352352        batch_control_read(batch);
    353         const int ret = uhci_hc_schedule(hc, batch);
    354         if (ret != EOK) {
    355                 batch_dispose(batch);
    356                 return ret;
    357         }
    358         return EOK;
    359 }
    360 /*----------------------------------------------------------------------------*/
    361 usbhc_iface_t uhci_hc_iface = {
     353        const int ret = hc_schedule(hc, batch);
     354        if (ret != EOK) {
     355                batch_dispose(batch);
     356        }
     357        return ret;
     358}
     359/*----------------------------------------------------------------------------*/
     360usbhc_iface_t hc_iface = {
    362361        .reserve_default_address = reserve_default_address,
    363362        .release_default_address = release_default_address,
     
    369368        .interrupt_in = interrupt_in,
    370369
     370        .bulk_out = bulk_out,
    371371        .bulk_in = bulk_in,
    372         .bulk_out = bulk_out,
    373 
     372
     373        .control_write = control_write,
    374374        .control_read = control_read,
    375         .control_write = control_write,
    376375};
    377376/**
  • uspace/drv/uhci-hcd/iface.h

    rd8421c4 rf97717d9  
    3838#include <usbhc_iface.h>
    3939
    40 extern usbhc_iface_t uhci_hc_iface;
     40extern usbhc_iface_t hc_iface;
    4141
    4242#endif
  • uspace/drv/uhci-hcd/main.c

    rd8421c4 rf97717d9  
    6262int uhci_add_device(ddf_dev_t *device)
    6363{
    64         usb_log_info("uhci_add_device() called\n");
     64        usb_log_debug("uhci_add_device() called\n");
    6565        assert(device);
    6666        uhci_t *uhci = malloc(sizeof(uhci_t));
     
    7272        int ret = uhci_init(uhci, device);
    7373        if (ret != EOK) {
    74                 usb_log_error("Failed to initialzie UHCI driver.\n");
     74                usb_log_error("Failed to initialize UHCI driver: %s.\n",
     75                    str_error(ret));
    7576                return ret;
    7677        }
    7778        device->driver_data = uhci;
     79
     80        usb_log_info("Controlling new UHCI device `%s'.\n", device->name);
     81
    7882        return EOK;
    7983}
     
    8993int main(int argc, char *argv[])
    9094{
     95        printf(NAME ": HelenOS UHCI driver.\n");
     96
    9197        sleep(3); /* TODO: remove in final version */
    92         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     98        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    9399
    94100        return ddf_driver_main(&uhci_driver);
  • uspace/drv/uhci-hcd/transfer_list.c

    rd8421c4 rf97717d9  
    7979        if (!instance->queue_head)
    8080                return;
    81         /* Set both next and element to point to the same QH */
     81        /* Set both queue_head.next to point to the follower */
    8282        qh_set_next_qh(instance->queue_head, next->queue_head_pa);
    83         qh_set_element_qh(instance->queue_head, next->queue_head_pa);
    8483}
    8584/*----------------------------------------------------------------------------*/
     
    9291 * The batch is added to the end of the list and queue.
    9392 */
    94 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch)
     93void transfer_list_add_batch(
     94    transfer_list_t *instance, usb_transfer_batch_t *batch)
    9595{
    9696        assert(instance);
     
    9898        usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
    9999
    100         const uint32_t pa = addr_to_phys(batch_qh(batch));
    101         assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    102 
    103         /* New batch will be added to the end of the current list
    104          * so set the link accordingly */
    105         qh_set_next_qh(batch_qh(batch), instance->queue_head->next);
    106 
    107100        fibril_mutex_lock(&instance->guard);
    108101
     102        qh_t *last_qh = NULL;
    109103        /* Add to the hardware queue. */
    110104        if (list_empty(&instance->batch_list)) {
    111105                /* There is nothing scheduled */
    112                 qh_t *qh = instance->queue_head;
    113                 assert(qh->element == qh->next);
    114                 qh_set_element_qh(qh, pa);
     106                last_qh = instance->queue_head;
    115107        } else {
    116108                /* There is something scheduled */
    117109                usb_transfer_batch_t *last = list_get_instance(
    118110                    instance->batch_list.prev, usb_transfer_batch_t, link);
    119                 qh_set_next_qh(batch_qh(last), pa);
    120         }
     111                last_qh = batch_qh(last);
     112        }
     113        const uint32_t pa = addr_to_phys(batch_qh(batch));
     114        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
     115
     116        /* keep link */
     117        batch_qh(batch)->next = last_qh->next;
     118        qh_set_next_qh(last_qh, pa);
     119
    121120        /* Add to the driver list */
    122121        list_append(&batch->link, &instance->batch_list);
     
    148147        while (current != &instance->batch_list) {
    149148                link_t *next = current->next;
    150                 usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link);
     149                usb_transfer_batch_t *batch =
     150                    list_get_instance(current, usb_transfer_batch_t, link);
    151151
    152152                if (batch_is_complete(batch)) {
     
    162162                link_t *item = done.next;
    163163                list_remove(item);
    164                 usb_transfer_batch_t *batch = list_get_instance(item, usb_transfer_batch_t, link);
     164                usb_transfer_batch_t *batch =
     165                    list_get_instance(item, usb_transfer_batch_t, link);
    165166                batch->next_step(batch);
    166167        }
     
    174175{
    175176        fibril_mutex_lock(&instance->guard);
    176         while (list_empty(&instance->batch_list)) {
     177        while (!list_empty(&instance->batch_list)) {
    177178                link_t *current = instance->batch_list.next;
    178                 usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link);
     179                usb_transfer_batch_t *batch =
     180                    list_get_instance(current, usb_transfer_batch_t, link);
    179181                transfer_list_remove_batch(instance, batch);
    180182                usb_transfer_batch_finish(batch, EIO);
     
    191193 * Does not lock the transfer list, caller is responsible for that.
    192194 */
    193 void transfer_list_remove_batch(transfer_list_t *instance, usb_transfer_batch_t *batch)
     195void transfer_list_remove_batch(
     196    transfer_list_t *instance, usb_transfer_batch_t *batch)
    194197{
    195198        assert(instance);
     
    197200        assert(batch);
    198201        assert(batch_qh(batch));
     202        assert(fibril_mutex_is_locked(&instance->guard));
     203
    199204        usb_log_debug2(
    200205            "Queue %s: removing batch(%p).\n", instance->name, batch);
    201206
    202         const char * pos = NULL;
     207        const char *qpos = NULL;
    203208        /* Remove from the hardware queue */
    204         if (batch->link.prev == &instance->batch_list) {
     209        if (instance->batch_list.next == &batch->link) {
    205210                /* I'm the first one here */
    206                 qh_set_element_qh(instance->queue_head, batch_qh(batch)->next);
    207                 pos = "FIRST";
     211                assert((instance->queue_head->next & LINK_POINTER_ADDRESS_MASK)
     212                    == addr_to_phys(batch_qh(batch)));
     213                instance->queue_head->next = batch_qh(batch)->next;
     214                qpos = "FIRST";
    208215        } else {
    209216                usb_transfer_batch_t *prev =
    210                     list_get_instance(batch->link.prev, usb_transfer_batch_t, link);
    211                 qh_set_next_qh(batch_qh(prev), batch_qh(batch)->next);
    212                 pos = "NOT FIRST";
    213         }
    214         /* Remove from the driver list */
     217                    list_get_instance(
     218                        batch->link.prev, usb_transfer_batch_t, link);
     219                assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK)
     220                    == addr_to_phys(batch_qh(batch)));
     221                batch_qh(prev)->next = batch_qh(batch)->next;
     222                qpos = "NOT FIRST";
     223        }
     224        /* Remove from the batch list */
    215225        list_remove(&batch->link);
    216         usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n",
    217             batch, pos, instance->name, batch_qh(batch)->next);
     226        usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n",
     227            batch, qpos, instance->name, batch_qh(batch)->next);
    218228}
    219229/**
  • uspace/drv/uhci-hcd/transfer_list.h

    rd8421c4 rf97717d9  
    3737#include <fibril_synch.h>
    3838
    39 #include "uhci_struct/queue_head.h"
    40 
    4139#include "batch.h"
     40#include "hw_struct/queue_head.h"
    4241
    4342typedef struct transfer_list
  • uspace/drv/uhci-hcd/uhci.c

    rd8421c4 rf97717d9  
    5454{
    5555        assert(dev);
    56         uhci_hc_t *hc = &((uhci_t*)dev->driver_data)->hc;
     56        hc_t *hc = &((uhci_t*)dev->driver_data)->hc;
    5757        uint16_t status = IPC_GET_ARG1(*call);
    5858        assert(hc);
    59         uhci_hc_interrupt(hc, status);
     59        hc_interrupt(hc, status);
    6060}
    6161/*----------------------------------------------------------------------------*/
     
    7070{
    7171        assert(fun);
    72         usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc.device_manager;
     72        usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc.manager;
    7373
    7474        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    107107};
    108108/*----------------------------------------------------------------------------*/
    109 static ddf_dev_ops_t uhci_hc_ops = {
     109static ddf_dev_ops_t hc_ops = {
    110110        .interfaces[USB_DEV_IFACE] = &usb_iface,
    111         .interfaces[USBHC_DEV_IFACE] = &uhci_hc_iface, /* see iface.h/c */
     111        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    112112};
    113113/*----------------------------------------------------------------------------*/
     
    120120{
    121121        assert(fun);
    122         return &((uhci_rh_t*)fun->driver_data)->resource_list;
     122        return &((rh_t*)fun->driver_data)->resource_list;
    123123}
    124124/*----------------------------------------------------------------------------*/
     
    128128};
    129129/*----------------------------------------------------------------------------*/
    130 static ddf_dev_ops_t uhci_rh_ops = {
     130static ddf_dev_ops_t rh_ops = {
    131131        .interfaces[USB_DEV_IFACE] = &usb_iface,
    132132        .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface
     
    167167        CHECK_RET_DEST_FUN_RETURN(ret,
    168168            "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
    169         usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
     169        usb_log_debug("I/O regs at 0x%X (size %zu), IRQ %d.\n",
    170170            io_reg_base, io_reg_size, irq);
    171171
     
    175175
    176176        bool interrupts = false;
     177#ifdef CONFIG_USBHC_NO_INTERRUPTS
     178        usb_log_warning("Interrupts disabled in OS config, " \
     179            "falling back to polling.\n");
     180#else
    177181        ret = pci_enable_interrupts(device);
    178182        if (ret != EOK) {
    179                 usb_log_warning(
    180                     "Failed(%d) to enable interrupts, fall back to polling.\n",
    181                     ret);
     183                usb_log_warning("Failed to enable interrupts: %s.\n",
     184                    str_error(ret));
     185                usb_log_info("HW interrupts not available, " \
     186                    "falling back to polling.\n");
    182187        } else {
    183188                usb_log_debug("Hw interrupts enabled.\n");
    184189                interrupts = true;
    185190        }
     191#endif
    186192
    187193        instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
     
    190196            "Failed(%d) to create HC function.\n", ret);
    191197
    192         ret = uhci_hc_init(&instance->hc, instance->hc_fun,
     198        ret = hc_init(&instance->hc, instance->hc_fun,
    193199            (void*)io_reg_base, io_reg_size, interrupts);
    194200        CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret);
    195         instance->hc_fun->ops = &uhci_hc_ops;
     201        instance->hc_fun->ops = &hc_ops;
    196202        instance->hc_fun->driver_data = &instance->hc;
    197203        ret = ddf_fun_bind(instance->hc_fun);
     
    208214        if (instance->rh_fun) \
    209215                ddf_fun_destroy(instance->rh_fun); \
    210         uhci_hc_fini(&instance->hc); \
     216        hc_fini(&instance->hc); \
    211217        return ret; \
    212218}
     
    223229            "Failed(%d) to create root hub function.\n", ret);
    224230
    225         ret = uhci_rh_init(&instance->rh, instance->rh_fun,
     231        ret = rh_init(&instance->rh, instance->rh_fun,
    226232            (uintptr_t)instance->hc.registers + 0x10, 4);
    227233        CHECK_RET_FINI_RETURN(ret,
    228234            "Failed(%d) to setup UHCI root hub.\n", ret);
    229235
    230         instance->rh_fun->ops = &uhci_rh_ops;
     236        instance->rh_fun->ops = &rh_ops;
    231237        instance->rh_fun->driver_data = &instance->rh;
    232238        ret = ddf_fun_bind(instance->rh_fun);
  • uspace/drv/uhci-hcd/uhci.h

    rd8421c4 rf97717d9  
    3838#include <ddf/driver.h>
    3939
    40 #include "uhci_hc.h"
    41 #include "uhci_rh.h"
     40#include "hc.h"
     41#include "root_hub.h"
    4242
    4343typedef struct uhci {
     
    4545        ddf_fun_t *rh_fun;
    4646
    47         uhci_hc_t hc;
    48         uhci_rh_t rh;
     47        hc_t hc;
     48        rh_t rh;
    4949} uhci_t;
    5050
  • uspace/drv/uhci-hcd/utils/malloc32.h

    rd8421c4 rf97717d9  
    5050static inline uintptr_t addr_to_phys(void *addr)
    5151{
     52        if (addr == NULL)
     53                return 0;
     54
    5255        uintptr_t result;
    5356        int ret = as_get_physical_mapping(addr, &result);
  • uspace/drv/uhci-rhd/main.c

    rd8421c4 rf97717d9  
    3636#include <device/hw_res.h>
    3737#include <errno.h>
     38#include <str_error.h>
    3839#include <usb_iface.h>
    3940#include <usb/ddfiface.h>
     
    8687        int ret = hc_get_my_registers(device, &io_regs, &io_size);
    8788        if (ret != EOK) {
    88                 usb_log_error("Failed(%d) to get registers from parent hc.",
    89                     ret);
    90         }
    91         usb_log_info("I/O regs at %#X (size %zu).\n", io_regs, io_size);
     89                usb_log_error("Failed to get registers from parent HC: %s.\n",
     90                    str_error(ret));
     91        }
     92        usb_log_debug("I/O regs at %#X (size %zu).\n", io_regs, io_size);
    9293
    9394        uhci_root_hub_t *rh = malloc(sizeof(uhci_root_hub_t));
     
    99100        ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
    100101        if (ret != EOK) {
    101                 usb_log_error("Failed(%d) to initialize driver instance.\n", ret);
     102                usb_log_error("Failed to initialize driver instance: %s.\n",
     103                    str_error(ret));
    102104                free(rh);
    103105                return ret;
     
    105107
    106108        device->driver_data = rh;
    107         usb_log_info("Sucessfully initialized driver instance for device:%d.\n",
    108             device->handle);
     109        usb_log_info("Controlling root hub `%s' (%llu).\n",
     110            device->name, device->handle);
    109111        return EOK;
    110112}
     
    129131int main(int argc, char *argv[])
    130132{
    131         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     133        printf(NAME ": HelenOS UHCI root hub driver.\n");
     134
     135        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
     136
    132137        return ddf_driver_main(&uhci_rh_driver);
    133138}
  • uspace/drv/uhci-rhd/port.c

    rd8421c4 rf97717d9  
    256256        assert(usb_hc_connection_is_opened(&port->hc_connection));
    257257
    258         usb_log_info("%s: Detected new device.\n", port->id_string);
     258        usb_log_debug("%s: Detected new device.\n", port->id_string);
    259259
    260260        usb_address_t dev_addr;
     
    270270        }
    271271
    272         usb_log_info("%s: New device has address %d (handle %zu).\n",
    273             port->id_string, dev_addr, port->attached_device);
     272        usb_log_info("New device at port %u, address %d (handle %llu).\n",
     273            port->number, dev_addr, port->attached_device);
    274274
    275275        return EOK;
     
    315315        uhci_port_write_status(port, port_status);
    316316
    317         usb_log_info("%s: %sabled port.\n",
     317        usb_log_debug("%s: %sabled port.\n",
    318318                port->id_string, enabled ? "En" : "Dis");
    319319        return EOK;
  • uspace/drv/usbflbk/main.c

    rd8421c4 rf97717d9  
    8686int main(int argc, char *argv[])
    8787{
    88         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     88        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    8989
    9090        return usb_driver_main(&usbfallback_driver);
  • uspace/drv/usbhub/main.c

    rd8421c4 rf97717d9  
    7676        printf(NAME ": HelenOS USB hub driver.\n");
    7777
    78         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     78        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    7979       
    8080        return usb_driver_main(&usb_hub_driver);
  • uspace/drv/usbhub/usbhub.c

    rd8421c4 rf97717d9  
    132132                return opResult;
    133133        }
    134         usb_log_info("setting port count to %d\n",descriptor->ports_count);
     134        usb_log_debug("setting port count to %d\n",descriptor->ports_count);
    135135        hub_info->port_count = descriptor->ports_count;
    136136        hub_info->attached_devs = (usb_hc_attached_device_t*)
     
    159159        usb_standard_device_descriptor_t *std_descriptor
    160160            = &hub_info->usb_device->descriptors.device;
    161         usb_log_info("hub has %d configurations\n",
     161        usb_log_debug("hub has %d configurations\n",
    162162            std_descriptor->configuration_count);
    163163        if(std_descriptor->configuration_count<1){
     
    288288        //if this hub already uses default address, it cannot request it once more
    289289        if(hub->is_default_address_used) return;
    290         usb_log_info("some connection changed\n");
     290        usb_log_debug("some connection changed\n");
    291291        assert(hub->control_pipe->hc_phone);
    292292        int opResult = usb_hub_clear_port_feature(hub->control_pipe,
     
    331331
    332332        int opResult;
    333         usb_log_info("finalizing add device\n");
     333        usb_log_debug("finalizing add device\n");
    334334        opResult = usb_hub_clear_port_feature(hub->control_pipe,
    335335            port, USB_HUB_FEATURE_C_PORT_RESET);
     
    363363                return;
    364364        }
    365         usb_log_info("setting new address %d\n",new_device_address);
     365        usb_log_debug("setting new address %d\n",new_device_address);
    366366        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    367367        //    new_device_address);
     
    403403                return;
    404404        }
    405         usb_log_info("new device address %d, handle %zu\n",
     405        usb_log_info("Detected new device on `%s' (port %d), " \
     406            "address %d (handle %llu).\n",
     407            hub->usb_device->ddf_dev->name, (int) port,
    406408            new_device_address, child_handle);
    407 
    408409}
    409410
     
    502503        if (usb_port_connect_change(&status)) {
    503504                if (usb_port_dev_connected(&status)) {
    504                         usb_log_info("some connection changed\n");
     505                        usb_log_debug("some connection changed\n");
    505506                        usb_hub_init_add_device(hub, port, usb_port_speed(&status));
    506507                } else {
     
    514515                        usb_hub_over_current(hub,port);
    515516                }else{
    516                         usb_log_info("over current condition was auto-resolved on port %d\n",
     517                        usb_log_debug("over current condition was auto-resolved on port %d\n",
    517518                                        port);
    518519                }
     
    520521        //port reset
    521522        if (usb_port_reset_completed(&status)) {
    522                 usb_log_info("port reset complete\n");
     523                usb_log_debug("port reset complete\n");
    523524                if (usb_port_enabled(&status)) {
    524525                        usb_hub_finalize_add_device(hub, port, usb_port_speed(&status));
  • uspace/drv/usbmid/main.c

    rd8421c4 rf97717d9  
    106106        printf(NAME ": USB multi interface device driver.\n");
    107107
    108         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     108        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    109109        return ddf_driver_main(&mid_driver);
    110110}
  • uspace/drv/usbmouse/main.c

    rd8421c4 rf97717d9  
    9090int main(int argc, char *argv[])
    9191{
    92         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     92        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    9393
    9494        return usb_driver_main(&mouse_driver);
  • uspace/drv/vhc/hcd.c

    rd8421c4 rf97717d9  
    122122        //sleep(5);
    123123
    124         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     124        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    125125
    126126        printf(NAME ": virtual USB host controller driver.\n");
  • uspace/lib/usb/Makefile

    rd8421c4 rf97717d9  
    5050        src/usb.c \
    5151        src/usbdevice.c \
     52        src/hidreq.c \
     53        src/hidreport.c \
    5254        src/host/device_keeper.c \
    5355        src/host/batch.c
  • uspace/lib/usb/include/usb/classes/hidparser.h

    rd8421c4 rf97717d9  
    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/debug.h

    rd8421c4 rf97717d9  
    7979} usb_log_level_t;
    8080
     81/** Default log level. */
     82#define USB_LOG_LEVEL_DEFAULT USB_LOG_LEVEL_DEBUG
     83
    8184
    8285void usb_log_enable(usb_log_level_t, const char *);
  • uspace/lib/usb/include/usb/request.h

    rd8421c4 rf97717d9  
    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

    rd8421c4 rf97717d9  
    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

    rd8421c4 rf97717d9  
    214214        fibril_mutex_lock(&instance->guard);
    215215
    216         usb_address_t new_address = instance->last_address + 1;
    217         while (instance->devices[new_address].occupied) {
     216        usb_address_t new_address = instance->last_address;
     217        do {
     218                ++new_address;
     219                if (new_address > USB11_ADDRESS_MAX)
     220                        new_address = 1;
    218221                if (new_address == instance->last_address) {
    219222                        fibril_mutex_unlock(&instance->guard);
    220223                        return ENOSPC;
    221224                }
    222                 if (new_address == USB11_ADDRESS_MAX)
    223                         new_address = 1;
    224                 ++new_address;
    225         }
     225        } while (instance->devices[new_address].occupied);
    226226
    227227        assert(new_address != USB_ADDRESS_DEFAULT);
Note: See TracChangeset for help on using the changeset viewer.