Changeset 8e9becf6 in mainline


Ignore:
Timestamp:
2011-03-08T20:00:47Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
021351c
Parents:
0588062e (diff), d2fc1c2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merged branch lelian/hidd

Files:
4 added
2 deleted
61 edited
1 moved

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r0588062e r8e9becf6  
    8484./uspace/drv/test1/test1
    8585./uspace/drv/test2/test2
     86./uspace/drv/ehci-hcd/ehci-hcd
    8687./uspace/drv/uhci-hcd/uhci-hcd
    8788./uspace/drv/uhci-rhd/uhci-rhd
  • boot/arch/amd64/Makefile.inc

    r0588062e r8e9becf6  
    4343        isa \
    4444        ns8250 \
     45        ehci-hcd \
    4546        uhci-hcd \
    4647        uhci-rhd \
  • boot/arch/mips32/src/asm.S

    r0588062e r8e9becf6  
    4141
    4242start:
    43         /* Setup CPU map (on msim this code
    44            is executed in parallel on all CPUs,
    45            but it not an issue) */
     43        /*
     44         * Setup the CP0 configuration
     45         *  - Disable 64-bit kernel addressing mode
     46         *  - DIsable 64-bit supervisor adressing mode
     47         *  - Disable 64-bit user addressing mode
     48         */
     49        mfc0 $a0, $status
     50        la $a1, 0xffffff1f
     51        and $a0, $a1, $a0
     52        mtc0 $a0, $status
     53       
     54        /*
     55         * Setup CPU map (on msim this code
     56         * is executed in parallel on all CPUs,
     57         * but it not an issue).
     58         */
    4659        la $a0, PA2KA(CPUMAP_OFFSET)
    4760       
     
    94107        lw $k1, ($k0)
    95108       
    96         /* If we are not running on BSP
    97            then end in an infinite loop  */
     109        /*
     110         * If we are not running on BSP
     111         * then end in an infinite loop.
     112         */
    98113        beq $k1, $zero, bsp
    99114        nop
     
    127142
    128143jump_to_kernel:
    129         #
    130         # TODO:
    131         # Make sure that the I-cache, D-cache and memory are mutually coherent
    132         # before passing control to the copied code.
    133         #
     144        /*
     145         * TODO:
     146         *
     147         * Make sure that the I-cache, D-cache and memory are mutually
     148         * coherent before passing control to the copied code.
     149         */
    134150        j $a0
    135151        nop
  • uspace/Makefile

    r0588062e r8e9becf6  
    117117                srv/hw/irc/apic \
    118118                srv/hw/irc/i8259 \
     119                drv/ehci-hcd \
    119120                drv/uhci-hcd \
    120121                drv/uhci-rhd \
     
    134135                srv/hw/irc/apic \
    135136                srv/hw/irc/i8259 \
     137                drv/ehci-hcd \
    136138                drv/uhci-hcd \
    137139                drv/uhci-rhd \
  • uspace/app/bdsh/cmds/modules/mkfile/mkfile.c

    r0588062e r8e9becf6  
    125125
    126126        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    127                 c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind);
     127                c = getopt_long(argc, argv, "s:h", long_options, &opt_ind);
    128128                switch (c) {
    129129                case 'h':
  • uspace/doc/doxygroups.h

    r0588062e r8e9becf6  
    256256         */
    257257
     258        /**
     259         * @defgroup drvusbehci EHCI driver
     260         * @ingroup usb
     261         * @brief Driver for EHCI host controller.
     262         */
     263
     264
  • uspace/drv/ehci-hcd/pci.h

    r0588062e r8e9becf6  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libusb
     29/** @addtogroup drvusbehci
    3030 * @{
    3131 */
    3232/** @file
    33  * @brief Common definitions for both HC driver and hub driver.
     33 * PCI related functions needed by EHCI driver.
    3434 */
    35 #ifndef LIBUSB_HCDHUBD_PRIVATE_H_
    36 #define LIBUSB_HCDHUBD_PRIVATE_H_
     35#ifndef DRV_EHCI_PCI_H
     36#define DRV_EHCI_PCI_H
    3737
    38 #define USB_HUB_DEVICE_NAME "usbhub"
    39 #define USB_KBD_DEVICE_NAME "hid"
     38#include <ddf/driver.h>
    4039
    41 extern link_t hc_list;
    42 extern usb_hc_driver_t *hc_driver;
    43 
    44 extern usbhc_iface_t usbhc_interface;
    45 
    46 usb_address_t usb_get_address_by_handle(devman_handle_t);
    47 int usb_add_hc_device(device_t *);
    48 
    49 /** lowest allowed usb address */
    50 extern int usb_lowest_address;
    51 
    52 /** highest allowed usb address */
    53 extern int usb_highest_address;
    54 
    55 /**
    56  * @brief initialize address list of given hcd
    57  *
    58  * This function should be used only for hcd initialization.
    59  * It creates interval list of free addresses, thus it is initialized as
    60  * list with one interval with whole address space. Using an address shrinks
    61  * the interval, freeing an address extends an interval or creates a
    62  * new one.
    63  *
    64  * @param hcd
    65  * @return
    66  */
    67 void  usb_create_address_list(usb_hc_device_t * hcd);
    68 
    69 
    70 
    71 
    72 
     40int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
     41int pci_enable_interrupts(ddf_dev_t *);
     42int pci_disable_legacy(ddf_dev_t *);
    7343
    7444#endif
     
    7646 * @}
    7747 */
     48
  • uspace/drv/pciintel/pci.c

    r0588062e r8e9becf6  
    9494  sysarg_t apic;
    9595  sysarg_t i8259;
     96
    9697        int irc_phone = -1;
    9798        int irc_service = 0;
     
    103104        }
    104105
    105   if (irc_service) {
    106     while (irc_phone < 0)
    107       irc_phone = service_connect_blocking(irc_service, 0, 0);
    108   } else {
     106  if (irc_service == 0)
    109107                return false;
    110         }
     108
     109        irc_phone = service_connect_blocking(irc_service, 0, 0);
     110        if (irc_phone < 0)
     111                return false;
    111112
    112113        size_t i;
     
    114115                if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
    115116                        int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
    116                         async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     117                        int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     118                        if (rc != EOK) {
     119                                async_hangup(irc_phone);
     120                                return false;
     121                        }
    117122                }
    118123        }
     
    122127}
    123128
    124 static int pci_config_space_write_16(ddf_fun_t *fun, uint32_t address, uint16_t data)
     129static int pci_config_space_write_32(
     130    ddf_fun_t *fun, uint32_t address, uint32_t data)
     131{
     132        if (address > 252)
     133                return EINVAL;
     134        pci_conf_write_32(PCI_FUN(fun), address, data);
     135        return EOK;
     136}
     137
     138static int pci_config_space_write_16(
     139    ddf_fun_t *fun, uint32_t address, uint16_t data)
    125140{
    126141        if (address > 254)
     
    130145}
    131146
     147static int pci_config_space_write_8(
     148    ddf_fun_t *fun, uint32_t address, uint8_t data)
     149{
     150        if (address > 255)
     151                return EINVAL;
     152        pci_conf_write_8(PCI_FUN(fun), address, data);
     153        return EOK;
     154}
     155
     156static int pci_config_space_read_32(
     157    ddf_fun_t *fun, uint32_t address, uint32_t *data)
     158{
     159        if (address > 252)
     160                return EINVAL;
     161        *data = pci_conf_read_32(PCI_FUN(fun), address);
     162        return EOK;
     163}
     164
     165static int pci_config_space_read_16(
     166    ddf_fun_t *fun, uint32_t address, uint16_t *data)
     167{
     168        if (address > 254)
     169                return EINVAL;
     170        *data = pci_conf_read_16(PCI_FUN(fun), address);
     171        return EOK;
     172}
     173
     174static int pci_config_space_read_8(
     175    ddf_fun_t *fun, uint32_t address, uint8_t *data)
     176{
     177        if (address > 255)
     178                return EINVAL;
     179        *data = pci_conf_read_8(PCI_FUN(fun), address);
     180        return EOK;
     181}
    132182
    133183static hw_res_ops_t pciintel_hw_res_ops = {
     
    137187
    138188static pci_dev_iface_t pci_dev_ops = {
    139         .config_space_read_8 = NULL,
    140         .config_space_read_16 = NULL,
    141         .config_space_read_32 = NULL,
    142         .config_space_write_8 = NULL,
     189        .config_space_read_8 = &pci_config_space_read_8,
     190        .config_space_read_16 = &pci_config_space_read_16,
     191        .config_space_read_32 = &pci_config_space_read_32,
     192        .config_space_write_8 = &pci_config_space_write_8,
    143193        .config_space_write_16 = &pci_config_space_write_16,
    144         .config_space_write_32 = NULL
     194        .config_space_write_32 = &pci_config_space_write_32
    145195};
    146196
  • uspace/drv/uhci-hcd/batch.c

    r0588062e r8e9becf6  
    3535#include <str_error.h>
    3636
     37#include <usb/usb.h>
    3738#include <usb/debug.h>
    3839
     
    4647static int batch_schedule(batch_t *instance);
    4748
     49static void batch_control(batch_t *instance,
     50    usb_packet_id data_stage, usb_packet_id status_stage);
     51static void batch_data(batch_t *instance, usb_packet_id pid);
    4852static void batch_call_in(batch_t *instance);
    4953static void batch_call_out(batch_t *instance);
    5054static void batch_call_in_and_dispose(batch_t *instance);
    5155static void batch_call_out_and_dispose(batch_t *instance);
    52 
    53 
     56static void batch_dispose(batch_t *instance);
     57
     58
     59/** Allocates memory and initializes internal data structures.
     60 *
     61 * @param[in] fun DDF function to pass to callback.
     62 * @param[in] target Device and endpoint target of the transaction.
     63 * @param[in] transfer_type Interrupt, Control or Bulk.
     64 * @param[in] max_packet_size maximum allowed size of data packets.
     65 * @param[in] speed Speed of the transaction.
     66 * @param[in] buffer Data source/destination.
     67 * @param[in] size Size of the buffer.
     68 * @param[in] setup_buffer Setup data source (if not NULL)
     69 * @param[in] setup_size Size of setup_buffer (should be always 8)
     70 * @param[in] func_in function to call on inbound transaction completion
     71 * @param[in] func_out function to call on outbound transaction completion
     72 * @param[in] arg additional parameter to func_in or func_out
     73 * @param[in] manager Pointer to toggle management structure.
     74 * @return False, if there is an active TD, true otherwise.
     75 */
    5476batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    5577    usb_transfer_type_t transfer_type, size_t max_packet_size,
     
    5779    char* setup_buffer, size_t setup_size,
    5880    usbhc_iface_transfer_in_callback_t func_in,
    59     usbhc_iface_transfer_out_callback_t func_out, void *arg)
     81    usbhc_iface_transfer_out_callback_t func_out, void *arg,
     82    device_keeper_t *manager
     83    )
    6084{
    6185        assert(func_in == NULL || func_out == NULL);
    6286        assert(func_in != NULL || func_out != NULL);
    6387
     88#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
     89        if (ptr == NULL) { \
     90                usb_log_error(message); \
     91                if (instance) { \
     92                        batch_dispose(instance); \
     93                } \
     94                return NULL; \
     95        } else (void)0
     96
    6497        batch_t *instance = malloc(sizeof(batch_t));
    65         if (instance == NULL) {
    66                 usb_log_error("Failed to allocate batch instance.\n");
    67                 return NULL;
    68         }
    69 
    70         instance->qh = queue_head_get();
    71         if (instance->qh == NULL) {
    72                 usb_log_error("Failed to allocate queue head.\n");
    73                 free(instance);
    74                 return NULL;
    75         }
     98        CHECK_NULL_DISPOSE_RETURN(instance,
     99            "Failed to allocate batch instance.\n");
     100        bzero(instance, sizeof(batch_t));
     101
     102        instance->qh = malloc32(sizeof(queue_head_t));
     103        CHECK_NULL_DISPOSE_RETURN(instance->qh,
     104            "Failed to allocate batch queue head.\n");
     105        queue_head_init(instance->qh);
    76106
    77107        instance->packets = (size + max_packet_size - 1) / max_packet_size;
     
    80110        }
    81111
    82         instance->tds = malloc32(sizeof(transfer_descriptor_t) * instance->packets);
    83         if (instance->tds == NULL) {
    84                 usb_log_error("Failed to allocate transfer descriptors.\n");
    85                 queue_head_dispose(instance->qh);
    86                 free(instance);
    87                 return NULL;
    88         }
    89         bzero(instance->tds, sizeof(transfer_descriptor_t) * instance->packets);
    90 
    91         const size_t transport_size = max_packet_size * instance->packets;
    92 
    93         instance->transport_buffer =
    94            (size > 0) ? malloc32(transport_size) : NULL;
    95         if ((size > 0) && (instance->transport_buffer == NULL)) {
    96                 usb_log_error("Failed to allocate device accessible buffer.\n");
    97                 queue_head_dispose(instance->qh);
    98                 free32(instance->tds);
    99                 free(instance);
    100                 return NULL;
    101         }
    102 
    103         instance->setup_buffer = setup_buffer ? malloc32(setup_size) : NULL;
    104         if ((setup_size > 0) && (instance->setup_buffer == NULL)) {
    105                 usb_log_error("Failed to allocate device accessible setup buffer.\n");
    106                 queue_head_dispose(instance->qh);
    107                 free32(instance->tds);
    108                 free32(instance->transport_buffer);
    109                 free(instance);
    110                 return NULL;
    111         }
    112         if (instance->setup_buffer) {
     112        instance->tds = malloc32(sizeof(td_t) * instance->packets);
     113        CHECK_NULL_DISPOSE_RETURN(
     114            instance->tds, "Failed to allocate transfer descriptors.\n");
     115        bzero(instance->tds, sizeof(td_t) * instance->packets);
     116
     117//      const size_t transport_size = max_packet_size * instance->packets;
     118
     119        if (size > 0) {
     120                instance->transport_buffer = malloc32(size);
     121                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
     122                    "Failed to allocate device accessible buffer.\n");
     123        }
     124
     125        if (setup_size > 0) {
     126                instance->setup_buffer = malloc32(setup_size);
     127                CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
     128                    "Failed to allocate device accessible setup buffer.\n");
    113129                memcpy(instance->setup_buffer, setup_buffer, setup_size);
    114130        }
    115131
     132
     133        link_initialize(&instance->link);
     134
    116135        instance->max_packet_size = max_packet_size;
    117 
    118         link_initialize(&instance->link);
    119 
    120136        instance->target = target;
    121137        instance->transfer_type = transfer_type;
    122 
    123         if (func_out)
    124                 instance->callback_out = func_out;
    125         if (func_in)
    126                 instance->callback_in = func_in;
    127 
    128138        instance->buffer = buffer;
    129139        instance->buffer_size = size;
     
    132142        instance->arg = arg;
    133143        instance->speed = speed;
    134 
    135         queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
     144        instance->manager = manager;
     145
     146        if (func_out)
     147                instance->callback_out = func_out;
     148        if (func_in)
     149                instance->callback_in = func_in;
     150
     151        queue_head_set_element_td(instance->qh, addr_to_phys(instance->tds));
     152
    136153        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    137154            instance, target.address, target.endpoint);
     
    139156}
    140157/*----------------------------------------------------------------------------*/
     158/** Checks batch TDs for activity.
     159 *
     160 * @param[in] instance Batch structure to use.
     161 * @return False, if there is an active TD, true otherwise.
     162 */
    141163bool batch_is_complete(batch_t *instance)
    142164{
     
    147169        size_t i = 0;
    148170        for (;i < instance->packets; ++i) {
    149                 if (transfer_descriptor_is_active(&instance->tds[i])) {
     171                if (td_is_active(&instance->tds[i])) {
    150172                        return false;
    151173                }
    152                 instance->error = transfer_descriptor_status(&instance->tds[i]);
     174
     175                instance->error = td_status(&instance->tds[i]);
    153176                if (instance->error != EOK) {
     177                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
     178                            instance, i, instance->tds[i].status);
     179
     180                        device_keeper_set_toggle(instance->manager,
     181                            instance->target, td_toggle(&instance->tds[i]));
    154182                        if (i > 0)
    155                                 instance->transfered_size -= instance->setup_size;
    156                         usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    157                           instance, i, instance->tds[i].status);
     183                                goto substract_ret;
    158184                        return true;
    159185                }
    160                 instance->transfered_size +=
    161                     transfer_descriptor_actual_size(&instance->tds[i]);
    162         }
     186
     187                instance->transfered_size += td_act_size(&instance->tds[i]);
     188                if (td_is_short(&instance->tds[i]))
     189                        goto substract_ret;
     190        }
     191substract_ret:
    163192        instance->transfered_size -= instance->setup_size;
    164193        return true;
    165194}
    166195/*----------------------------------------------------------------------------*/
     196/** Prepares control write transaction.
     197 *
     198 * @param[in] instance Batch structure to use.
     199 */
    167200void batch_control_write(batch_t *instance)
    168201{
    169202        assert(instance);
    170 
     203        /* we are data out, we are supposed to provide data */
     204        memcpy(instance->transport_buffer, instance->buffer,
     205            instance->buffer_size);
     206        batch_control(instance, USB_PID_OUT, USB_PID_IN);
     207        instance->next_step = batch_call_out_and_dispose;
     208        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     209        batch_schedule(instance);
     210}
     211/*----------------------------------------------------------------------------*/
     212/** Prepares control read transaction.
     213 *
     214 * @param[in] instance Batch structure to use.
     215 */
     216void batch_control_read(batch_t *instance)
     217{
     218        assert(instance);
     219        batch_control(instance, USB_PID_IN, USB_PID_OUT);
     220        instance->next_step = batch_call_in_and_dispose;
     221        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
     222        batch_schedule(instance);
     223}
     224/*----------------------------------------------------------------------------*/
     225/** Prepares interrupt in transaction.
     226 *
     227 * @param[in] instance Batch structure to use.
     228 */
     229void batch_interrupt_in(batch_t *instance)
     230{
     231        assert(instance);
     232        batch_data(instance, USB_PID_IN);
     233        instance->next_step = batch_call_in_and_dispose;
     234        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
     235        batch_schedule(instance);
     236}
     237/*----------------------------------------------------------------------------*/
     238/** Prepares interrupt out transaction.
     239 *
     240 * @param[in] instance Batch structure to use.
     241 */
     242void batch_interrupt_out(batch_t *instance)
     243{
     244        assert(instance);
    171245        /* we are data out, we are supposed to provide data */
    172246        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     247        batch_data(instance, USB_PID_OUT);
     248        instance->next_step = batch_call_out_and_dispose;
     249        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
     250        batch_schedule(instance);
     251}
     252/*----------------------------------------------------------------------------*/
     253/** Prepares bulk in transaction.
     254 *
     255 * @param[in] instance Batch structure to use.
     256 */
     257void batch_bulk_in(batch_t *instance)
     258{
     259        assert(instance);
     260        batch_data(instance, USB_PID_IN);
     261        instance->next_step = batch_call_in_and_dispose;
     262        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     263        batch_schedule(instance);
     264}
     265/*----------------------------------------------------------------------------*/
     266/** Prepares bulk out transaction.
     267 *
     268 * @param[in] instance Batch structure to use.
     269 */
     270void batch_bulk_out(batch_t *instance)
     271{
     272        assert(instance);
     273        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     274        batch_data(instance, USB_PID_OUT);
     275        instance->next_step = batch_call_out_and_dispose;
     276        usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
     277        batch_schedule(instance);
     278}
     279/*----------------------------------------------------------------------------*/
     280/** Prepares generic data transaction
     281 *
     282 * @param[in] instance Batch structure to use.
     283 * @param[in] pid to use for data packets.
     284 */
     285void batch_data(batch_t *instance, usb_packet_id pid)
     286{
     287        assert(instance);
     288        const bool low_speed = instance->speed == USB_SPEED_LOW;
     289        int toggle =
     290            device_keeper_get_toggle(instance->manager, instance->target);
     291        assert(toggle == 0 || toggle == 1);
     292
     293        size_t packet = 0;
     294        size_t remain_size = instance->buffer_size;
     295        while (remain_size > 0) {
     296                char *data =
     297                    instance->transport_buffer + instance->buffer_size
     298                    - remain_size;
     299
     300                const size_t packet_size =
     301                    (instance->max_packet_size > remain_size) ?
     302                    remain_size : instance->max_packet_size;
     303
     304                td_t *next_packet = (packet + 1 < instance->packets)
     305                    ? &instance->tds[packet + 1] : NULL;
     306
     307                assert(packet < instance->packets);
     308                assert(packet_size <= remain_size);
     309
     310                td_init(
     311                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     312                    toggle, false, low_speed, instance->target, pid, data,
     313                    next_packet);
     314
     315
     316                toggle = 1 - toggle;
     317                remain_size -= packet_size;
     318                ++packet;
     319        }
     320        device_keeper_set_toggle(instance->manager, instance->target, toggle);
     321}
     322/*----------------------------------------------------------------------------*/
     323/** Prepares generic control transaction
     324 *
     325 * @param[in] instance Batch structure to use.
     326 * @param[in] data_stage to use for data packets.
     327 * @param[in] status_stage to use for data packets.
     328 */
     329void batch_control(batch_t *instance,
     330   usb_packet_id data_stage, usb_packet_id status_stage)
     331{
     332        assert(instance);
    173333
    174334        const bool low_speed = instance->speed == USB_SPEED_LOW;
    175335        int toggle = 0;
    176336        /* setup stage */
    177         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    178             instance->setup_size, toggle, false, low_speed,
    179             instance->target, USB_PID_SETUP, instance->setup_buffer,
    180             &instance->tds[1]);
    181 
    182         /* data stage */
    183         size_t i = 1;
    184         for (;i < instance->packets - 1; ++i) {
    185                 char *data =
    186                     instance->transport_buffer + ((i - 1) * instance->max_packet_size);
    187                 toggle = 1 - toggle;
    188 
    189                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    190                     instance->max_packet_size, toggle++, false, low_speed,
    191                     instance->target, USB_PID_OUT, data, &instance->tds[i + 1]);
    192         }
    193 
    194         /* status stage */
    195         i = instance->packets - 1;
    196         transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    197             0, 1, false, low_speed, instance->target, USB_PID_IN, NULL, NULL);
    198 
    199         instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    200         usb_log_debug2("Control write last TD status: %x.\n",
    201                 instance->tds[i].status);
    202 
    203         instance->next_step = batch_call_out_and_dispose;
    204         usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
    205         batch_schedule(instance);
    206 }
    207 /*----------------------------------------------------------------------------*/
    208 void batch_control_read(batch_t *instance)
    209 {
    210         assert(instance);
    211 
    212         const bool low_speed = instance->speed == USB_SPEED_LOW;
    213         int toggle = 0;
    214         /* setup stage */
    215         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
     337        td_init(instance->tds, DEFAULT_ERROR_COUNT,
    216338            instance->setup_size, toggle, false, low_speed, instance->target,
    217339            USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
    218340
    219341        /* data stage */
    220         size_t i = 1;
    221         for (;i < instance->packets - 1; ++i) {
     342        size_t packet = 1;
     343        size_t remain_size = instance->buffer_size;
     344        while (remain_size > 0) {
    222345                char *data =
    223                     instance->transport_buffer + ((i - 1) * instance->max_packet_size);
     346                    instance->transport_buffer + instance->buffer_size
     347                    - remain_size;
     348
    224349                toggle = 1 - toggle;
    225350
    226                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    227                     instance->max_packet_size, toggle, false, low_speed,
    228                                 instance->target, USB_PID_IN, data, &instance->tds[i + 1]);
     351                const size_t packet_size =
     352                    (instance->max_packet_size > remain_size) ?
     353                    remain_size : instance->max_packet_size;
     354
     355                td_init(
     356                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     357                    toggle, false, low_speed, instance->target, data_stage,
     358                    data, &instance->tds[packet + 1]);
     359
     360                ++packet;
     361                assert(packet < instance->packets);
     362                assert(packet_size <= remain_size);
     363                remain_size -= packet_size;
    229364        }
    230365
    231366        /* status stage */
    232         i = instance->packets - 1;
    233         transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    234             0, 1, false, low_speed, instance->target, USB_PID_OUT, NULL, NULL);
    235 
    236         instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    237         usb_log_debug2("Control read last TD status: %x.\n",
    238                 instance->tds[i].status);
    239 
    240         instance->next_step = batch_call_in_and_dispose;
    241         usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    242         batch_schedule(instance);
    243 }
    244 /*----------------------------------------------------------------------------*/
    245 void batch_interrupt_in(batch_t *instance)
    246 {
    247         assert(instance);
    248 
    249         const bool low_speed = instance->speed == USB_SPEED_LOW;
    250         int toggle = 1;
    251         size_t i = 0;
    252         for (;i < instance->packets; ++i) {
    253                 char *data =
    254                     instance->transport_buffer + (i  * instance->max_packet_size);
    255                 transfer_descriptor_t *next = (i + 1) < instance->packets ?
    256                     &instance->tds[i + 1] : NULL;
    257                 toggle = 1 - toggle;
    258 
    259                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    260                     instance->max_packet_size, toggle, false, low_speed,
    261                     instance->target, USB_PID_IN, data, next);
    262         }
    263 
    264         instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    265 
    266         instance->next_step = batch_call_in_and_dispose;
    267         usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
    268         batch_schedule(instance);
    269 }
    270 /*----------------------------------------------------------------------------*/
    271 void batch_interrupt_out(batch_t *instance)
    272 {
    273         assert(instance);
    274 
    275         memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    276 
    277         const bool low_speed = instance->speed == USB_SPEED_LOW;
    278         int toggle = 1;
    279         size_t i = 0;
    280         for (;i < instance->packets; ++i) {
    281                 char *data =
    282                     instance->transport_buffer + (i  * instance->max_packet_size);
    283                 transfer_descriptor_t *next = (i + 1) < instance->packets ?
    284                     &instance->tds[i + 1] : NULL;
    285                 toggle = 1 - toggle;
    286 
    287                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    288                     instance->max_packet_size, toggle++, false, low_speed,
    289                     instance->target, USB_PID_OUT, data, next);
    290         }
    291 
    292         instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    293 
    294         instance->next_step = batch_call_out_and_dispose;
    295         usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
    296         batch_schedule(instance);
    297 }
    298 /*----------------------------------------------------------------------------*/
     367        assert(packet == instance->packets - 1);
     368        td_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
     369            0, 1, false, low_speed, instance->target, status_stage, NULL, NULL);
     370
     371
     372        instance->tds[packet].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     373        usb_log_debug2("Control last TD status: %x.\n",
     374            instance->tds[packet].status);
     375}
     376/*----------------------------------------------------------------------------*/
     377/** Prepares data, gets error status and calls callback in.
     378 *
     379 * @param[in] instance Batch structure to use.
     380 */
    299381void batch_call_in(batch_t *instance)
    300382{
     
    302384        assert(instance->callback_in);
    303385
    304         memcpy(instance->buffer, instance->transport_buffer, instance->buffer_size);
     386        /* we are data in, we need data */
     387        memcpy(instance->buffer, instance->transport_buffer,
     388            instance->buffer_size);
    305389
    306390        int err = instance->error;
     
    309393            instance->transfered_size);
    310394
    311         instance->callback_in(instance->fun,
    312             err, instance->transfered_size,
    313             instance->arg);
    314 }
    315 /*----------------------------------------------------------------------------*/
     395        instance->callback_in(
     396            instance->fun, err, instance->transfered_size, instance->arg);
     397}
     398/*----------------------------------------------------------------------------*/
     399/** Gets error status and calls callback out.
     400 *
     401 * @param[in] instance Batch structure to use.
     402 */
    316403void batch_call_out(batch_t *instance)
    317404{
     
    326413}
    327414/*----------------------------------------------------------------------------*/
     415/** Prepares data, gets error status, calls callback in and dispose.
     416 *
     417 * @param[in] instance Batch structure to use.
     418 */
    328419void batch_call_in_and_dispose(batch_t *instance)
    329420{
    330421        assert(instance);
    331422        batch_call_in(instance);
     423        batch_dispose(instance);
     424}
     425/*----------------------------------------------------------------------------*/
     426/** Gets error status, calls callback out and dispose.
     427 *
     428 * @param[in] instance Batch structure to use.
     429 */
     430void batch_call_out_and_dispose(batch_t *instance)
     431{
     432        assert(instance);
     433        batch_call_out(instance);
     434        batch_dispose(instance);
     435}
     436/*----------------------------------------------------------------------------*/
     437/** Correctly disposes all used data structures.
     438 *
     439 * @param[in] instance Batch structure to use.
     440 */
     441void batch_dispose(batch_t *instance)
     442{
     443        assert(instance);
    332444        usb_log_debug("Batch(%p) disposing.\n", instance);
     445        /* free32 is NULL safe */
    333446        free32(instance->tds);
    334447        free32(instance->qh);
     
    338451}
    339452/*----------------------------------------------------------------------------*/
    340 void batch_call_out_and_dispose(batch_t *instance)
    341 {
    342         assert(instance);
    343         batch_call_out(instance);
    344         usb_log_debug("Batch(%p) disposing.\n", instance);
    345         free32(instance->tds);
    346         free32(instance->qh);
    347         free32(instance->setup_buffer);
    348         free32(instance->transport_buffer);
    349         free(instance);
    350 }
    351 /*----------------------------------------------------------------------------*/
    352453int batch_schedule(batch_t *instance)
    353454{
  • uspace/drv/uhci-hcd/batch.h

    r0588062e r8e9becf6  
    4242#include "uhci_struct/transfer_descriptor.h"
    4343#include "uhci_struct/queue_head.h"
     44#include "utils/device_keeper.h"
    4445
    4546typedef struct batch
     
    6566        ddf_fun_t *fun;
    6667        queue_head_t *qh;
    67         transfer_descriptor_t *tds;
     68        td_t *tds;
    6869        void (*next_step)(struct batch*);
     70        device_keeper_t *manager;
    6971} batch_t;
    7072
     
    7476                char *setup_buffer, size_t setup_size,
    7577    usbhc_iface_transfer_in_callback_t func_in,
    76     usbhc_iface_transfer_out_callback_t func_out, void *arg);
     78    usbhc_iface_transfer_out_callback_t func_out, void *arg,
     79                device_keeper_t *manager
     80                );
    7781
    7882bool batch_is_complete(batch_t *instance);
     
    8690void batch_interrupt_out(batch_t *instance);
    8791
    88 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */
    89 void batch_control_setup_old(batch_t *instance);
     92void batch_bulk_in(batch_t *instance);
    9093
    91 void batch_control_write_data_old(batch_t *instance);
    92 
    93 void batch_control_read_data_old(batch_t *instance);
    94 
    95 void batch_control_write_status_old(batch_t *instance);
    96 
    97 void batch_control_read_status_old(batch_t *instance);
     94void batch_bulk_out(batch_t *instance);
    9895#endif
    9996/**
  • uspace/drv/uhci-hcd/iface.c

    r0588062e r8e9becf6  
    4343#include "utils/device_keeper.h"
    4444
     45/** Reserve default address interface function
     46 *
     47 * @param[in] fun DDF function that was called.
     48 * @param[in] speed Speed to associate with the new default address.
     49 * @return Error code.
     50 */
    4551/*----------------------------------------------------------------------------*/
    4652static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
     
    5460}
    5561/*----------------------------------------------------------------------------*/
     62/** Release default address interface function
     63 *
     64 * @param[in] fun DDF function that was called.
     65 * @return Error code.
     66 */
    5667static int release_default_address(ddf_fun_t *fun)
    5768{
     
    6475}
    6576/*----------------------------------------------------------------------------*/
     77/** Request address interface function
     78 *
     79 * @param[in] fun DDF function that was called.
     80 * @param[in] speed Speed to associate with the new default address.
     81 * @param[out] address Place to write a new address.
     82 * @return Error code.
     83 */
    6684static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    6785    usb_address_t *address)
     
    8098}
    8199/*----------------------------------------------------------------------------*/
     100/** Bind address interface function
     101 *
     102 * @param[in] fun DDF function that was called.
     103 * @param[in] address Address of the device
     104 * @param[in] handle Devman handle of the device driver.
     105 * @return Error code.
     106 */
    82107static int bind_address(
    83108  ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     
    91116}
    92117/*----------------------------------------------------------------------------*/
     118/** Release address interface function
     119 *
     120 * @param[in] fun DDF function that was called.
     121 * @param[in] address USB address to be released.
     122 * @return Error code.
     123 */
    93124static int release_address(ddf_fun_t *fun, usb_address_t address)
    94125{
     
    101132}
    102133/*----------------------------------------------------------------------------*/
     134/** Interrupt out transaction interface function
     135 *
     136 * @param[in] fun DDF function that was called.
     137 * @param[in] target USB device to write to.
     138 * @param[in] max_packet_size maximum size of data packet the device accepts
     139 * @param[in] data Source of data.
     140 * @param[in] size Size of data source.
     141 * @param[in] callback Function to call on transaction completion
     142 * @param[in] arg Additional for callback function.
     143 * @return Error code.
     144 */
    103145static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    104146    size_t max_packet_size, void *data, size_t size,
     
    114156
    115157        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    116             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
     158            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     159            &hc->device_manager);
    117160        if (!batch)
    118161                return ENOMEM;
     
    121164}
    122165/*----------------------------------------------------------------------------*/
     166/** Interrupt in transaction interface function
     167 *
     168 * @param[in] fun DDF function that was called.
     169 * @param[in] target USB device to write to.
     170 * @param[in] max_packet_size maximum size of data packet the device accepts
     171 * @param[out] data Data destination.
     172 * @param[in] size Size of data source.
     173 * @param[in] callback Function to call on transaction completion
     174 * @param[in] arg Additional for callback function.
     175 * @return Error code.
     176 */
    123177static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    124178    size_t max_packet_size, void *data, size_t size,
     
    133187
    134188        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    135             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
     189            max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     190                        &hc->device_manager);
    136191        if (!batch)
    137192                return ENOMEM;
     
    140195}
    141196/*----------------------------------------------------------------------------*/
     197/** Bulk out transaction interface function
     198 *
     199 * @param[in] fun DDF function that was called.
     200 * @param[in] target USB device to write to.
     201 * @param[in] max_packet_size maximum size of data packet the device accepts
     202 * @param[in] data Source of data.
     203 * @param[in] size Size of data source.
     204 * @param[in] callback Function to call on transaction completion
     205 * @param[in] arg Additional for callback function.
     206 * @return Error code.
     207 */
     208static int bulk_out(ddf_fun_t *fun, usb_target_t target,
     209    size_t max_packet_size, void *data, size_t size,
     210    usbhc_iface_transfer_out_callback_t callback, void *arg)
     211{
     212        assert(fun);
     213        uhci_t *hc = fun_to_uhci(fun);
     214        assert(hc);
     215        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     216
     217        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
     218            target.address, target.endpoint, size, max_packet_size);
     219
     220        batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
     221            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     222            &hc->device_manager);
     223        if (!batch)
     224                return ENOMEM;
     225        batch_bulk_out(batch);
     226        return EOK;
     227}
     228/*----------------------------------------------------------------------------*/
     229/** Bulk in transaction interface function
     230 *
     231 * @param[in] fun DDF function that was called.
     232 * @param[in] target USB device to write to.
     233 * @param[in] max_packet_size maximum size of data packet the device accepts
     234 * @param[out] data Data destination.
     235 * @param[in] size Size of data source.
     236 * @param[in] callback Function to call on transaction completion
     237 * @param[in] arg Additional for callback function.
     238 * @return Error code.
     239 */
     240static int bulk_in(ddf_fun_t *fun, usb_target_t target,
     241    size_t max_packet_size, void *data, size_t size,
     242    usbhc_iface_transfer_in_callback_t callback, void *arg)
     243{
     244        assert(fun);
     245        uhci_t *hc = fun_to_uhci(fun);
     246        assert(hc);
     247        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     248        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
     249            target.address, target.endpoint, size, max_packet_size);
     250
     251        batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
     252            max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     253            &hc->device_manager);
     254        if (!batch)
     255                return ENOMEM;
     256        batch_bulk_in(batch);
     257        return EOK;
     258}
     259/*----------------------------------------------------------------------------*/
     260/** Control write transaction interface function
     261 *
     262 * @param[in] fun DDF function that was called.
     263 * @param[in] target USB device to write to.
     264 * @param[in] max_packet_size maximum size of data packet the device accepts.
     265 * @param[in] setup_data Data to send with SETUP packet.
     266 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     267 * @param[in] data Source of data.
     268 * @param[in] size Size of data source.
     269 * @param[in] callback Function to call on transaction completion.
     270 * @param[in] arg Additional for callback function.
     271 * @return Error code.
     272 */
    142273static int control_write(ddf_fun_t *fun, usb_target_t target,
    143274    size_t max_packet_size,
     
    152283            target.address, target.endpoint, size, max_packet_size);
    153284
     285        if (setup_size != 8)
     286                return EINVAL;
     287
    154288        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    155289            max_packet_size, speed, data, size, setup_data, setup_size,
    156             NULL, callback, arg);
    157         if (!batch)
    158                 return ENOMEM;
     290            NULL, callback, arg, &hc->device_manager);
     291        if (!batch)
     292                return ENOMEM;
     293        device_keeper_reset_if_need(&hc->device_manager, target, setup_data);
    159294        batch_control_write(batch);
    160295        return EOK;
    161296}
    162297/*----------------------------------------------------------------------------*/
     298/** Control read transaction interface function
     299 *
     300 * @param[in] fun DDF function that was called.
     301 * @param[in] target USB device to write to.
     302 * @param[in] max_packet_size maximum size of data packet the device accepts.
     303 * @param[in] setup_data Data to send with SETUP packet.
     304 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     305 * @param[out] data Source of data.
     306 * @param[in] size Size of data source.
     307 * @param[in] callback Function to call on transaction completion.
     308 * @param[in] arg Additional for callback function.
     309 * @return Error code.
     310 */
    163311static int control_read(ddf_fun_t *fun, usb_target_t target,
    164312    size_t max_packet_size,
     
    175323        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    176324            max_packet_size, speed, data, size, setup_data, setup_size, callback,
    177             NULL, arg);
     325            NULL, arg, &hc->device_manager);
    178326        if (!batch)
    179327                return ENOMEM;
     
    181329        return EOK;
    182330}
    183 
    184 
    185331/*----------------------------------------------------------------------------*/
    186332usbhc_iface_t uhci_iface = {
     
    194340        .interrupt_in = interrupt_in,
    195341
     342        .bulk_in = bulk_in,
     343        .bulk_out = bulk_out,
     344
    196345        .control_read = control_read,
    197346        .control_write = control_write,
  • uspace/drv/uhci-hcd/main.c

    r0588062e r8e9becf6  
    6060};
    6161/*----------------------------------------------------------------------------*/
     62/** IRQ handling callback, identifies devic
     63 *
     64 * @param[in] dev DDF instance of the device to use.
     65 * @param[in] iid (Unused).
     66 * @param[in] call Pointer to the call that represents interrupt.
     67 */
    6268static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    6369{
     
    6975}
    7076/*----------------------------------------------------------------------------*/
    71 static int uhci_add_device(ddf_dev_t *device)
     77/** Initializes a new ddf driver instance of UHCI hcd.
     78 *
     79 * @param[in] device DDF instance of the device to initialize.
     80 * @return Error code.
     81 *
     82 * Gets and initialies hardware resources, disables any legacy support,
     83 * and reports root hub device.
     84 */
     85int uhci_add_device(ddf_dev_t *device)
    7286{
    7387        assert(device);
     
    96110        ret = pci_disable_legacy(device);
    97111        CHECK_RET_FREE_HC_RETURN(ret,
    98             "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
     112            "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
    99113
    100114#if 0
     
    113127
    114128        ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size);
    115         CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n",
    116             ret);
     129        CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret);
    117130#undef CHECK_RET_FREE_HC_RETURN
    118131
     
    155168}
    156169/*----------------------------------------------------------------------------*/
     170/** Initializes global driver structures (NONE).
     171 *
     172 * @param[in] argc Nmber of arguments in argv vector (ignored).
     173 * @param[in] argv Cmdline argument vector (ignored).
     174 * @return Error code.
     175 *
     176 * Driver debug level is set here.
     177 */
    157178int main(int argc, char *argv[])
    158179{
  • uspace/drv/uhci-hcd/pci.c

    r0588062e r8e9becf6  
    6565
    6666        int rc;
    67 
    6867        hw_resource_list_t hw_resources;
    6968        rc = hw_res_get_resource_list(parent_phone, &hw_resources);
     
    8281        for (i = 0; i < hw_resources.count; i++) {
    8382                hw_resource_t *res = &hw_resources.resources[i];
    84                 switch (res->type) {
    85                         case INTERRUPT:
    86                                 irq = res->res.interrupt.irq;
    87                                 irq_found = true;
    88                                 usb_log_debug2("Found interrupt: %d.\n", irq);
    89                                 break;
    90                         case IO_RANGE:
    91                                 io_address = res->res.io_range.address;
    92                                 io_size = res->res.io_range.size;
    93                                 usb_log_debug2("Found io: %llx %zu.\n",
    94                                     res->res.io_range.address, res->res.io_range.size);
    95                                 io_found = true;
    96                                 break;
    97                         default:
    98                                 break;
     83                switch (res->type)
     84                {
     85                case INTERRUPT:
     86                        irq = res->res.interrupt.irq;
     87                        irq_found = true;
     88                        usb_log_debug2("Found interrupt: %d.\n", irq);
     89                        break;
     90
     91                case IO_RANGE:
     92                        io_address = res->res.io_range.address;
     93                        io_size = res->res.io_range.size;
     94                        usb_log_debug2("Found io: %llx %zu.\n",
     95                            res->res.io_range.address, res->res.io_range.size);
     96                        io_found = true;
     97
     98                default:
     99                        break;
    99100                }
    100101        }
    101102
    102         if (!io_found) {
    103                 rc = ENOENT;
    104                 goto leave;
    105         }
    106 
    107         if (!irq_found) {
     103        if (!io_found || !irq_found) {
    108104                rc = ENOENT;
    109105                goto leave;
     
    121117}
    122118/*----------------------------------------------------------------------------*/
     119/** Calls the PCI driver with a request to enable interrupts
     120 *
     121 * @param[in] device Device asking for interrupts
     122 * @return Error code.
     123 */
    123124int pci_enable_interrupts(ddf_dev_t *device)
    124125{
     
    130131}
    131132/*----------------------------------------------------------------------------*/
     133/** Calls the PCI driver with a request to clear legacy support register
     134 *
     135 * @param[in] device Device asking to disable interrupts
     136 * @return Error code.
     137 */
    132138int pci_disable_legacy(ddf_dev_t *device)
    133139{
    134140        assert(device);
    135         int parent_phone = devman_parent_device_connect(device->handle,
    136                 IPC_FLAG_BLOCKING);
     141        int parent_phone =
     142            devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
    137143        if (parent_phone < 0) {
    138144                return parent_phone;
     
    144150        sysarg_t value = 0x8f00;
    145151
    146   int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
     152        int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    147153            IPC_M_CONFIG_SPACE_WRITE_16, address, value);
    148154        async_hangup(parent_phone);
    149155
    150   return rc;
     156        return rc;
    151157}
    152158/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/root_hub.c

    r0588062e r8e9becf6  
    4545
    4646/*----------------------------------------------------------------------------*/
    47 static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
    48     devman_handle_t *handle)
     47/** Gets handle of the respective hc (parent device).
     48 *
     49 * @param[in] root_hub_fun Root hub function seeking hc handle.
     50 * @param[out] handle Place to write the handle.
     51 * @return Error code.
     52 */
     53static int usb_iface_get_hc_handle_rh_impl(
     54    ddf_fun_t *root_hub_fun, devman_handle_t *handle)
    4955{
     56        /* TODO: Can't this use parent pointer? */
    5057        ddf_fun_t *hc_fun = root_hub_fun->driver_data;
    5158        assert(hc_fun != NULL);
     
    5663}
    5764/*----------------------------------------------------------------------------*/
    58 static int usb_iface_get_address_rh_impl(ddf_fun_t *fun, devman_handle_t handle,
    59     usb_address_t *address)
     65/** Gets USB address of the calling device.
     66 *
     67 * @param[in] fun Root hub function.
     68 * @param[in] handle Handle of the device seeking address.
     69 * @param[out] address Place to store found address.
     70 * @return Error code.
     71 */
     72static int usb_iface_get_address_rh_impl(
     73    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
    6074{
     75        /* TODO: What does this do? Is it neccessary? Can't it use implemented
     76         * hc function?*/
    6177        assert(fun);
    6278        ddf_fun_t *hc_fun = fun->driver_data;
     
    6581        assert(hc);
    6682
    67         usb_address_t addr = device_keeper_find(&hc->device_manager,
    68             handle);
     83        usb_address_t addr = device_keeper_find(&hc->device_manager, handle);
    6984        if (addr < 0) {
    7085                return addr;
     
    8398};
    8499/*----------------------------------------------------------------------------*/
     100/** Gets root hub hw resources.
     101 *
     102 * @param[in] fun Root hub function.
     103 * @return Pointer to the resource list used by the root hub.
     104 */
    85105static hw_resource_list_t *get_resource_list(ddf_fun_t *dev)
    86106{
     
    91111        assert(hc);
    92112
    93         //TODO: fix memory leak
     113        /* TODO: fix memory leak */
    94114        hw_resource_list_t *resource_list = malloc(sizeof(hw_resource_list_t));
    95115        assert(resource_list);
  • uspace/drv/uhci-hcd/transfer_list.c

    r0588062e r8e9becf6  
    3838#include "transfer_list.h"
    3939
     40static void transfer_list_remove_batch(
     41    transfer_list_t *instance, batch_t *batch);
     42/*----------------------------------------------------------------------------*/
     43/** Initializes transfer list structures.
     44 *
     45 * @param[in] instance Memory place to use.
     46 * @param[in] name Name of te new list.
     47 * @return Error code
     48 *
     49 * Allocates memory for internat queue_head_t structure.
     50 */
    4051int transfer_list_init(transfer_list_t *instance, const char *name)
    4152{
     
    4354        instance->next = NULL;
    4455        instance->name = name;
    45         instance->queue_head = queue_head_get();
     56        instance->queue_head = malloc32(sizeof(queue_head_t));
    4657        if (!instance->queue_head) {
    4758                usb_log_error("Failed to allocate queue head.\n");
    4859                return ENOMEM;
    4960        }
    50         instance->queue_head_pa = (uintptr_t)addr_to_phys(instance->queue_head);
     61        instance->queue_head_pa = addr_to_phys(instance->queue_head);
    5162
    5263        queue_head_init(instance->queue_head);
     
    5667}
    5768/*----------------------------------------------------------------------------*/
     69/** Set the next list in chain.
     70 *
     71 * @param[in] instance List to lead.
     72 * @param[in] next List to append.
     73 * @return Error code
     74 */
    5875void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
    5976{
     
    6683}
    6784/*----------------------------------------------------------------------------*/
     85/** Submits a new transfer batch to list and queue.
     86 *
     87 * @param[in] instance List to use.
     88 * @param[in] batch Transfer batch to submit.
     89 * @return Error code
     90 */
    6891void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch)
    6992{
    7093        assert(instance);
    7194        assert(batch);
    72         usb_log_debug2("Adding batch(%p) to queue %s.\n", batch, instance->name);
     95        usb_log_debug2(
     96            "Adding batch(%p) to queue %s.\n", batch, instance->name);
    7397
    7498        uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);
     
    97121        queue_head_append_qh(last->qh, pa);
    98122        list_append(&batch->link, &instance->batch_list);
     123
    99124        usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n",
    100                 batch, instance->name, first );
     125                batch, instance->name, first);
    101126        fibril_mutex_unlock(&instance->guard);
    102127}
    103128/*----------------------------------------------------------------------------*/
    104 static void transfer_list_remove_batch(
    105     transfer_list_t *instance, batch_t *batch)
     129/** Removes a transfer batch from list and queue.
     130 *
     131 * @param[in] instance List to use.
     132 * @param[in] batch Transfer batch to remove.
     133 * @return Error code
     134 */
     135void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch)
    106136{
    107137        assert(instance);
     
    109139        assert(instance->queue_head);
    110140        assert(batch->qh);
    111         usb_log_debug2("Removing batch(%p) from queue %s.\n", batch, instance->name);
     141        usb_log_debug2(
     142            "Removing batch(%p) from queue %s.\n", batch, instance->name);
    112143
    113         /* I'm the first one here */
    114144        if (batch->link.prev == &instance->batch_list) {
    115                 usb_log_debug("Batch(%p) removed (FIRST) from queue %s, next element %x.\n",
    116                         batch, instance->name, batch->qh->next_queue);
     145                /* I'm the first one here */
     146                usb_log_debug(
     147                    "Batch(%p) removed (FIRST) from %s, next element %x.\n",
     148                    batch, instance->name, batch->qh->next_queue);
    117149                instance->queue_head->element = batch->qh->next_queue;
    118150        } else {
    119                 usb_log_debug("Batch(%p) removed (NOT FIRST) from queue, next element %x.\n",
    120                         batch, instance->name, batch->qh->next_queue);
    121                 batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
     151                usb_log_debug(
     152                    "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n",
     153                    batch, instance->name, batch->qh->next_queue);
     154                batch_t *prev =
     155                    list_get_instance(batch->link.prev, batch_t, link);
    122156                prev->qh->next_queue = batch->qh->next_queue;
    123157        }
     
    125159}
    126160/*----------------------------------------------------------------------------*/
     161/** Checks list for finished transfers.
     162 *
     163 * @param[in] instance List to use.
     164 * @return Error code
     165 */
    127166void transfer_list_remove_finished(transfer_list_t *instance)
    128167{
  • uspace/drv/uhci-hcd/transfer_list.h

    r0588062e r8e9becf6  
    5858{
    5959        assert(instance);
    60         queue_head_dispose(instance->queue_head);
     60        free32(instance->queue_head);
    6161}
    6262void transfer_list_remove_finished(transfer_list_t *instance);
  • uspace/drv/uhci-hcd/uhci.c

    r0588062e r8e9becf6  
    6161};
    6262
    63 static int usb_iface_get_address(ddf_fun_t *fun, devman_handle_t handle,
    64     usb_address_t *address)
     63/** Gets USB address of the calling device.
     64 *
     65 * @param[in] fun UHCI hc function.
     66 * @param[in] handle Handle of the device seeking address.
     67 * @param[out] address Place to store found address.
     68 * @return Error code.
     69 */
     70static int usb_iface_get_address(
     71    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
    6572{
    6673        assert(fun);
     
    99106
    100107static bool allowed_usb_packet(
    101         bool low_speed, usb_transfer_type_t, size_t size);
    102 
    103 
     108    bool low_speed, usb_transfer_type_t transfer, size_t size);
     109/*----------------------------------------------------------------------------*/
     110/** Initializes UHCI hcd driver structure
     111 *
     112 * @param[in] instance Memory place to initialize.
     113 * @param[in] dev DDF device.
     114 * @param[in] regs Address of I/O control registers.
     115 * @param[in] size Size of I/O control registers.
     116 * @return Error code.
     117 * @note Should be called only once on any structure.
     118 */
    104119int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size)
    105120{
     
    156171}
    157172/*----------------------------------------------------------------------------*/
     173/** Initializes UHCI hcd hw resources.
     174 *
     175 * @param[in] instance UHCI structure to use.
     176 */
    158177void uhci_init_hw(uhci_t *instance)
    159178{
    160179        assert(instance);
    161 
    162         /* reset everything, who knows what touched it before us */
    163         pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
     180        regs_t *registers = instance->registers;
     181
     182        /* Reset everything, who knows what touched it before us */
     183        pio_write_16(&registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
    164184        async_usleep(10000); /* 10ms according to USB spec */
    165         pio_write_16(&instance->registers->usbcmd, 0);
    166 
    167         /* reset hc, all states and counters */
    168         pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);
    169         while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)
    170                 { async_usleep(10); }
    171 
    172         /* set framelist pointer */
     185        pio_write_16(&registers->usbcmd, 0);
     186
     187        /* Reset hc, all states and counters */
     188        pio_write_16(&registers->usbcmd, UHCI_CMD_HCRESET);
     189        do { async_usleep(10); }
     190        while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
     191
     192        /* Set framelist pointer */
    173193        const uint32_t pa = addr_to_phys(instance->frame_list);
    174         pio_write_32(&instance->registers->flbaseadd, pa);
    175 
    176         /* enable all interrupts, but resume interrupt */
    177         pio_write_16(&instance->registers->usbintr,
    178             UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     194        pio_write_32(&registers->flbaseadd, pa);
     195
     196        /* Enable all interrupts, but resume interrupt */
     197//      pio_write_16(&instance->registers->usbintr,
     198//          UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     199
     200        uint16_t status = pio_read_16(&registers->usbcmd);
     201        if (status != 0)
     202                usb_log_warning("Previous command value: %x.\n", status);
    179203
    180204        /* Start the hc with large(64B) packet FSBR */
    181         pio_write_16(&instance->registers->usbcmd,
     205        pio_write_16(&registers->usbcmd,
    182206            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
    183207}
    184208/*----------------------------------------------------------------------------*/
     209/** Initializes UHCI hcd memory structures.
     210 *
     211 * @param[in] instance UHCI structure to use.
     212 * @return Error code
     213 * @note Should be called only once on any structure.
     214 */
    185215int uhci_init_mem_structures(uhci_t *instance)
    186216{
     
    194224        } else (void) 0
    195225
    196         /* init interrupt code */
     226        /* Init interrupt code */
    197227        instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds));
    198228        int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK;
    199         CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to allocate interrupt cmds space.\n");
     229        CHECK_RET_DEST_CMDS_RETURN(ret,
     230            "Failed to allocate interrupt cmds space.\n");
    200231
    201232        {
    202233                irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds;
    203234                memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
    204                 interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
    205                 interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
     235                interrupt_commands[0].addr =
     236                    (void*)&instance->registers->usbsts;
     237                interrupt_commands[1].addr =
     238                    (void*)&instance->registers->usbsts;
    206239                instance->interrupt_code.cmdcount =
    207240                    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
    208241        }
    209242
    210         /* init transfer lists */
     243        /* Init transfer lists */
    211244        ret = uhci_init_transfer_lists(instance);
    212         CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to initialize transfer lists.\n");
     245        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n");
    213246        usb_log_debug("Initialized transfer lists.\n");
    214247
    215         /* frame list initialization */
     248        /* Init USB frame list page*/
    216249        instance->frame_list = get_page();
    217250        ret = instance ? EOK : ENOMEM;
     
    219252        usb_log_debug("Initialized frame list.\n");
    220253
    221         /* initialize all frames to point to the first queue head */
     254        /* Set all frames to point to the first queue head */
    222255        const uint32_t queue =
    223256          instance->transfers_interrupt.queue_head_pa
     
    229262        }
    230263
    231         /* init address keeper(libusb) */
     264        /* Init device keeper*/
    232265        device_keeper_init(&instance->device_manager);
    233266        usb_log_debug("Initialized device manager.\n");
     
    237270}
    238271/*----------------------------------------------------------------------------*/
     272/** Initializes UHCI hcd transfer lists.
     273 *
     274 * @param[in] instance UHCI structure to use.
     275 * @return Error code
     276 * @note Should be called only once on any structure.
     277 */
    239278int uhci_init_transfer_lists(uhci_t *instance)
    240279{
     
    255294        CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list.");
    256295
    257         ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL");
     296        ret = transfer_list_init(
     297            &instance->transfers_control_full, "CONTROL_FULL");
    258298        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list.");
    259299
    260         ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW");
     300        ret = transfer_list_init(
     301            &instance->transfers_control_slow, "CONTROL_SLOW");
    261302        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list.");
    262303
     
    277318#endif
    278319
    279         instance->transfers[0][USB_TRANSFER_INTERRUPT] =
     320        /* Assign pointers to be used during scheduling */
     321        instance->transfers[USB_SPEED_FULL][USB_TRANSFER_INTERRUPT] =
    280322          &instance->transfers_interrupt;
    281         instance->transfers[1][USB_TRANSFER_INTERRUPT] =
     323        instance->transfers[USB_SPEED_LOW][USB_TRANSFER_INTERRUPT] =
    282324          &instance->transfers_interrupt;
    283         instance->transfers[0][USB_TRANSFER_CONTROL] =
     325        instance->transfers[USB_SPEED_FULL][USB_TRANSFER_CONTROL] =
    284326          &instance->transfers_control_full;
    285         instance->transfers[1][USB_TRANSFER_CONTROL] =
     327        instance->transfers[USB_SPEED_LOW][USB_TRANSFER_CONTROL] =
    286328          &instance->transfers_control_slow;
    287         instance->transfers[0][USB_TRANSFER_BULK] =
     329        instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] =
    288330          &instance->transfers_bulk_full;
    289331
     
    292334}
    293335/*----------------------------------------------------------------------------*/
     336/** Schedules batch for execution.
     337 *
     338 * @param[in] instance UHCI structure to use.
     339 * @param[in] batch Transfer batch to schedule.
     340 * @return Error code
     341 */
    294342int uhci_schedule(uhci_t *instance, batch_t *batch)
    295343{
     
    299347        if (!allowed_usb_packet(
    300348            low_speed, batch->transfer_type, batch->max_packet_size)) {
    301                 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",
     349                usb_log_warning(
     350                    "Invalid USB packet specified %s SPEED %d %zu.\n",
    302351                    low_speed ? "LOW" : "FULL" , batch->transfer_type,
    303352                    batch->max_packet_size);
     
    314363}
    315364/*----------------------------------------------------------------------------*/
     365/** Takes action based on the interrupt cause.
     366 *
     367 * @param[in] instance UHCI structure to use.
     368 * @param[in] status Value of the stsatus regiser at the time of interrupt.
     369 */
    316370void uhci_interrupt(uhci_t *instance, uint16_t status)
    317371{
    318372        assert(instance);
     373        /* TODO: Check interrupt cause here */
    319374        transfer_list_remove_finished(&instance->transfers_interrupt);
    320375        transfer_list_remove_finished(&instance->transfers_control_slow);
     
    323378}
    324379/*----------------------------------------------------------------------------*/
     380/** Polling function, emulates interrupts.
     381 *
     382 * @param[in] arg UHCI structure to use.
     383 * @return EOK
     384 */
    325385int uhci_interrupt_emulator(void* arg)
    326386{
     
    336396                uhci_interrupt(instance, status);
    337397                pio_write_16(&instance->registers->usbsts, 0x1f);
    338                 async_usleep(UHCI_CLEANER_TIMEOUT * 5);
     398                async_usleep(UHCI_CLEANER_TIMEOUT);
    339399        }
    340400        return EOK;
    341401}
    342402/*---------------------------------------------------------------------------*/
     403/** Debug function, checks consistency of memory structures.
     404 *
     405 * @param[in] arg UHCI structure to use.
     406 * @return EOK
     407 */
    343408int uhci_debug_checker(void *arg)
    344409{
     
    399464                async_usleep(UHCI_DEBUGER_TIMEOUT);
    400465        }
    401         return 0;
     466        return EOK;
    402467#undef QH
    403468}
    404469/*----------------------------------------------------------------------------*/
     470/** Checks transfer packets, for USB validity
     471 *
     472 * @param[in] low_speed Transfer speed.
     473 * @param[in] transfer Transer type
     474 * @param[in] size Maximum size of used packets
     475 * @return EOK
     476 */
    405477bool allowed_usb_packet(
    406478    bool low_speed, usb_transfer_type_t transfer, size_t size)
  • uspace/drv/uhci-hcd/uhci.h

    r0588062e r8e9becf6  
    8484        device_keeper_t device_manager;
    8585
    86         volatile regs_t *registers;
     86        regs_t *registers;
    8787
    8888        link_pointer_t *frame_list;
  • uspace/drv/uhci-hcd/uhci_struct/queue_head.h

    r0588062e r8e9becf6  
    7171}
    7272
    73 static inline void queue_head_element_td(queue_head_t *instance, uint32_t pa)
     73static inline void queue_head_set_element_td(queue_head_t *instance, uint32_t pa)
    7474{
    7575        if (pa) {
     
    7878}
    7979
    80 static inline queue_head_t * queue_head_get() {
    81         queue_head_t *ret = malloc32(sizeof(queue_head_t));
    82         if (ret)
    83                 queue_head_init(ret);
    84         return ret;
    85 }
    86 
    87 static inline void queue_head_dispose(queue_head_t *head)
    88         { free32(head); }
    89 
    90 
    9180#endif
    9281/**
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    r0588062e r8e9becf6  
    3838#include "utils/malloc32.h"
    3939
    40 void transfer_descriptor_init(transfer_descriptor_t *instance,
    41     int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,
    42     usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next)
     40/** Initializes Transfer Descriptor
     41 *
     42 * @param[in] instance Memory place to initialize.
     43 * @param[in] err_count Number of retries hc should attempt.
     44 * @param[in] size Size of data source.
     45 * @param[in] toggle Value of toggle bit.
     46 * @param[in] iso True if TD is for Isochronous transfer.
     47 * @param[in] low_speed Target device's speed.
     48 * @param[in] target Address and endpoint receiving the transfer.
     49 * @param[in] pid Packet identification (SETUP, IN or OUT).
     50 * @param[in] buffer Source of data.
     51 * @param[in] next Net TD in transaction.
     52 * @return Error code.
     53 */
     54void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso,
     55    bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
     56    td_t *next)
    4357{
    4458        assert(instance);
     59        assert(size < 1024);
     60        assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN)
     61            || (pid == USB_PID_OUT));
    4562
    4663        instance->next = 0
     
    4966
    5067        instance->status = 0
    51           | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
    52                 | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
    53           | TD_STATUS_ERROR_ACTIVE;
     68            | ((err_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
     69            | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
     70            | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0)
     71            | TD_STATUS_ERROR_ACTIVE;
    5472
    55         assert(size < 1024);
     73        if (pid == USB_PID_IN && !iso) {
     74                instance->status |= TD_STATUS_SPD_FLAG;
     75        }
     76
    5677        instance->device = 0
    57                 | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
    58                 | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
    59                 | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
    60                 | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
    61                 | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
     78            | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
     79            | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
     80            | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
     81            | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
     82            | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
    6283
    6384        instance->buffer_ptr = 0;
     
    6889
    6990        usb_log_debug2("Created TD: %X:%X:%X:%X(%p).\n",
    70                 instance->next, instance->status, instance->device,
    71           instance->buffer_ptr, buffer);
     91            instance->next, instance->status, instance->device,
     92            instance->buffer_ptr, buffer);
     93        if (pid == USB_PID_SETUP) {
     94                usb_log_debug("SETUP BUFFER: %s\n",
     95                        usb_debug_str_buffer(buffer, 8, 8));
     96        }
    7297}
    7398/*----------------------------------------------------------------------------*/
    74 int transfer_descriptor_status(transfer_descriptor_t *instance)
     99/** Converts TD status into standard error code
     100 *
     101 * @param[in] instance TD structure to use.
     102 * @return Error code.
     103 */
     104int td_status(td_t *instance)
    75105{
    76106        assert(instance);
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    r0588062e r8e9becf6  
    8888         * we don't use it anyway
    8989         */
    90 } __attribute__((packed)) transfer_descriptor_t;
     90} __attribute__((packed)) td_t;
    9191
    9292
    93 void transfer_descriptor_init(transfer_descriptor_t *instance,
    94     int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,
    95     usb_target_t target, int pid, void *buffer, transfer_descriptor_t * next);
     93void td_init(td_t *instance, int error_count, size_t size, bool toggle, bool iso,
     94    bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
     95    td_t *next);
    9696
    97 int transfer_descriptor_status(transfer_descriptor_t *instance);
     97int td_status(td_t *instance);
    9898
    99 static inline size_t transfer_descriptor_actual_size(
    100     transfer_descriptor_t *instance)
     99static inline size_t td_act_size(td_t *instance)
    101100{
    102101        assert(instance);
    103102        return
    104             ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK;
     103            ((instance->status >> TD_STATUS_ACTLEN_POS) + 1)
     104            & TD_STATUS_ACTLEN_MASK;
    105105}
    106106
    107 static inline bool transfer_descriptor_is_active(
    108     transfer_descriptor_t *instance)
     107static inline bool td_is_short(td_t *instance)
     108{
     109        const size_t act_size = td_act_size(instance);
     110        const size_t max_size =
     111            ((instance->device >> TD_DEVICE_MAXLEN_POS) + 1)
     112            & TD_DEVICE_MAXLEN_MASK;
     113        return
     114            (instance->status | TD_STATUS_SPD_FLAG) && act_size < max_size;
     115}
     116
     117static inline int td_toggle(td_t *instance)
     118{
     119        assert(instance);
     120        return ((instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) != 0)
     121            ? 1 : 0;
     122}
     123
     124static inline bool td_is_active(td_t *instance)
    109125{
    110126        assert(instance);
  • uspace/drv/uhci-hcd/utils/device_keeper.c

    r0588062e r8e9becf6  
    3939
    4040/*----------------------------------------------------------------------------*/
     41/** Initializes device keeper structure.
     42 *
     43 * @param[in] instance Memory place to initialize.
     44 */
    4145void device_keeper_init(device_keeper_t *instance)
    4246{
     
    4953                instance->devices[i].occupied = false;
    5054                instance->devices[i].handle = 0;
    51         }
    52 }
    53 /*----------------------------------------------------------------------------*/
    54 void device_keeper_reserve_default(
    55     device_keeper_t *instance, usb_speed_t speed)
     55                instance->devices[i].toggle_status = 0;
     56        }
     57}
     58/*----------------------------------------------------------------------------*/
     59/** Attempts to obtain address 0, blocks.
     60 *
     61 * @param[in] instance Device keeper structure to use.
     62 * @param[in] speed Speed of the device requesting default address.
     63 */
     64void device_keeper_reserve_default(device_keeper_t *instance, usb_speed_t speed)
    5665{
    5766        assert(instance);
     
    6675}
    6776/*----------------------------------------------------------------------------*/
     77/** Attempts to obtain address 0, blocks.
     78 *
     79 * @param[in] instance Device keeper structure to use.
     80 * @param[in] speed Speed of the device requesting default address.
     81 */
    6882void device_keeper_release_default(device_keeper_t *instance)
    6983{
     
    7589}
    7690/*----------------------------------------------------------------------------*/
     91/** Checks setup data for signs of toggle reset.
     92 *
     93 * @param[in] instance Device keeper structure to use.
     94 * @param[in] target Device to receive setup packet.
     95 * @param[in] data Setup packet data.
     96 */
     97void device_keeper_reset_if_need(
     98    device_keeper_t *instance, usb_target_t target, const unsigned char *data)
     99{
     100        assert(instance);
     101        fibril_mutex_lock(&instance->guard);
     102        if (target.endpoint > 15 || target.endpoint < 0
     103            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     104            || !instance->devices[target.address].occupied) {
     105                fibril_mutex_unlock(&instance->guard);
     106                return;
     107        }
     108
     109        switch (data[1])
     110        {
     111        case 0x01: /*clear feature*/
     112                /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
     113                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     114                        /* endpoint number is < 16, thus first byte is enough */
     115                        instance->devices[target.address].toggle_status &=
     116                            ~(1 << data[4]);
     117                }
     118        break;
     119
     120        case 0x9: /* set configuration */
     121        case 0x11: /* set interface */
     122                instance->devices[target.address].toggle_status = 0;
     123        break;
     124        }
     125        fibril_mutex_unlock(&instance->guard);
     126}
     127/*----------------------------------------------------------------------------*/
     128/** Gets current value of endpoint toggle.
     129 *
     130 * @param[in] instance Device keeper structure to use.
     131 * @param[in] target Device and endpoint used.
     132 * @return Error code
     133 */
     134int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target)
     135{
     136        assert(instance);
     137        int ret;
     138        fibril_mutex_lock(&instance->guard);
     139        if (target.endpoint > 15 || target.endpoint < 0
     140            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     141            || !instance->devices[target.address].occupied) {
     142                ret = EINVAL;
     143        } else {
     144                ret =
     145                    (instance->devices[target.address].toggle_status
     146                        >> target.endpoint) & 1;
     147        }
     148        fibril_mutex_unlock(&instance->guard);
     149        return ret;
     150}
     151/*----------------------------------------------------------------------------*/
     152/** Sets current value of endpoint toggle.
     153 *
     154 * @param[in] instance Device keeper structure to use.
     155 * @param[in] target Device and endpoint used.
     156 * @param[in] toggle Current toggle value.
     157 * @return Error code.
     158 */
     159int device_keeper_set_toggle(
     160    device_keeper_t *instance, usb_target_t target, bool toggle)
     161{
     162        assert(instance);
     163        int ret;
     164        fibril_mutex_lock(&instance->guard);
     165        if (target.endpoint > 15 || target.endpoint < 0
     166            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     167            || !instance->devices[target.address].occupied) {
     168                ret = EINVAL;
     169        } else {
     170                if (toggle) {
     171                        instance->devices[target.address].toggle_status |= (1 << target.endpoint);
     172                } else {
     173                        instance->devices[target.address].toggle_status &= ~(1 << target.endpoint);
     174                }
     175                ret = EOK;
     176        }
     177        fibril_mutex_unlock(&instance->guard);
     178        return ret;
     179}
     180/*----------------------------------------------------------------------------*/
     181/** Gets a free USB address
     182 *
     183 * @param[in] instance Device keeper structure to use.
     184 * @param[in] speed Speed of the device requiring address.
     185 * @return Free address, or error code.
     186 */
    77187usb_address_t device_keeper_request(
    78188    device_keeper_t *instance, usb_speed_t speed)
     
    96206        instance->devices[new_address].occupied = true;
    97207        instance->devices[new_address].speed = speed;
     208        instance->devices[new_address].toggle_status = 0;
    98209        instance->last_address = new_address;
    99210        fibril_mutex_unlock(&instance->guard);
     
    101212}
    102213/*----------------------------------------------------------------------------*/
     214/** Binds USB address to devman handle.
     215 *
     216 * @param[in] instance Device keeper structure to use.
     217 * @param[in] address Device address
     218 * @param[in] handle Devman handle of the device.
     219 */
    103220void device_keeper_bind(
    104221    device_keeper_t *instance, usb_address_t address, devman_handle_t handle)
     
    113230}
    114231/*----------------------------------------------------------------------------*/
     232/** Releases used USB address.
     233 *
     234 * @param[in] instance Device keeper structure to use.
     235 * @param[in] address Device address
     236 */
    115237void device_keeper_release(device_keeper_t *instance, usb_address_t address)
    116238{
     
    125247}
    126248/*----------------------------------------------------------------------------*/
     249/** Finds USB address associated with the device
     250 *
     251 * @param[in] instance Device keeper structure to use.
     252 * @param[in] handle Devman handle of the device seeking its address.
     253 * @return USB Address, or error code.
     254 */
    127255usb_address_t device_keeper_find(
    128256    device_keeper_t *instance, devman_handle_t handle)
     
    142270}
    143271/*----------------------------------------------------------------------------*/
     272/** Gets speed associated with the address
     273 *
     274 * @param[in] instance Device keeper structure to use.
     275 * @param[in] address Address of the device.
     276 * @return USB speed.
     277 */
    144278usb_speed_t device_keeper_speed(
    145279    device_keeper_t *instance, usb_address_t address)
  • uspace/drv/uhci-hcd/utils/device_keeper.h

    r0588062e r8e9becf6  
    4444        usb_speed_t speed;
    4545        bool occupied;
     46        uint16_t toggle_status;
    4647        devman_handle_t handle;
    4748};
     
    5556
    5657void device_keeper_init(device_keeper_t *instance);
     58
    5759void device_keeper_reserve_default(
    5860    device_keeper_t *instance, usb_speed_t speed);
     61
    5962void device_keeper_release_default(device_keeper_t *instance);
     63
     64void device_keeper_reset_if_need(
     65    device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data);
     66
     67int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target);
     68
     69int device_keeper_set_toggle(
     70    device_keeper_t *instance, usb_target_t target, bool toggle);
    6071
    6172usb_address_t device_keeper_request(
    6273    device_keeper_t *instance, usb_speed_t speed);
     74
    6375void device_keeper_bind(
    6476    device_keeper_t *instance, usb_address_t address, devman_handle_t handle);
     77
    6578void device_keeper_release(device_keeper_t *instance, usb_address_t address);
     79
    6680usb_address_t device_keeper_find(
    6781    device_keeper_t *instance, devman_handle_t handle);
  • uspace/drv/uhci-hcd/utils/malloc32.h

    r0588062e r8e9becf6  
    3434#ifndef DRV_UHCI_TRANSLATOR_H
    3535#define DRV_UHCI_TRANSLATOR_H
    36 
    37 #include <usb/usbmem.h>
    3836
    3937#include <assert.h>
  • uspace/drv/uhci-rhd/main.c

    r0588062e r8e9becf6  
    3535#include <devman.h>
    3636#include <device/hw_res.h>
     37#include <errno.h>
    3738#include <usb_iface.h>
    3839#include <usb/ddfiface.h>
     40#include <usb/debug.h>
    3941
    40 #include <errno.h>
    4142
    42 #include <usb/debug.h>
    4343
    4444#include "root_hub.h"
     
    4747static int hc_get_my_registers(ddf_dev_t *dev,
    4848    uintptr_t *io_reg_address, size_t *io_reg_size);
    49 
     49/*----------------------------------------------------------------------------*/
    5050static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
    5151{
     
    5858        return EOK;
    5959}
    60 
     60/*----------------------------------------------------------------------------*/
    6161static usb_iface_t uhci_rh_usb_iface = {
    6262        .get_hc_handle = usb_iface_get_hc_handle,
    6363        .get_address = usb_iface_get_address_hub_impl
    6464};
    65 
     65/*----------------------------------------------------------------------------*/
    6666static ddf_dev_ops_t uhci_rh_ops = {
    6767        .interfaces[USB_DEV_IFACE] = &uhci_rh_usb_iface,
    6868};
    69 
     69/*----------------------------------------------------------------------------*/
     70/** Initializes a new ddf driver instance of UHCI root hub.
     71 *
     72 * @param[in] device DDF instance of the device to initialize.
     73 * @return Error code.
     74 */
    7075static int uhci_rh_add_device(ddf_dev_t *device)
    7176{
     
    104109        return EOK;
    105110}
    106 
     111/*----------------------------------------------------------------------------*/
    107112static driver_ops_t uhci_rh_driver_ops = {
    108113        .add_device = uhci_rh_add_device,
    109114};
    110 
     115/*----------------------------------------------------------------------------*/
    111116static driver_t uhci_rh_driver = {
    112117        .name = NAME,
     
    114119};
    115120/*----------------------------------------------------------------------------*/
     121/** Initializes global driver structures (NONE).
     122 *
     123 * @param[in] argc Nmber of arguments in argv vector (ignored).
     124 * @param[in] argv Cmdline argument vector (ignored).
     125 * @return Error code.
     126 *
     127 * Driver debug level is set here.
     128 */
    116129int main(int argc, char *argv[])
    117130{
     
    120133}
    121134/*----------------------------------------------------------------------------*/
    122 int hc_get_my_registers(ddf_dev_t *dev,
    123     uintptr_t *io_reg_address, size_t *io_reg_size)
     135/** Get address of I/O registers.
     136 *
     137 * @param[in] dev Device asking for the addresses.
     138 * @param[out] io_reg_address Base address of the memory range.
     139 * @param[out] io_reg_size Size of the memory range.
     140 * @return Error code.
     141 */
     142int hc_get_my_registers(
     143    ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
    124144{
    125145        assert(dev != NULL);
     
    146166        for (i = 0; i < hw_resources.count; i++) {
    147167                hw_resource_t *res = &hw_resources.resources[i];
    148                 switch (res->type) {
    149                         case IO_RANGE:
    150                                 io_address = (uintptr_t)
    151                                     res->res.io_range.address;
    152                                 io_size = res->res.io_range.size;
    153                                 io_found = true;
    154                                 break;
    155                         default:
    156                                 break;
     168                switch (res->type)
     169                {
     170                case IO_RANGE:
     171                        io_address = (uintptr_t) res->res.io_range.address;
     172                        io_size = res->res.io_range.size;
     173                        io_found = true;
     174
     175                default:
     176                        break;
    157177                }
    158178        }
     
    170190        }
    171191        rc = EOK;
     192
    172193leave:
    173194        async_hangup(parent_phone);
    174 
    175195        return rc;
    176196}
  • uspace/drv/uhci-rhd/port.c

    r0588062e r8e9becf6  
    4646#include "port_status.h"
    4747
    48 static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
     48static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
    4949static int uhci_port_remove_device(uhci_port_t *port);
    5050static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
    5151static int uhci_port_check(void *port);
    52 static int new_device_enable_port(int portno, void *arg);
    53 
    54 int uhci_port_init(
    55   uhci_port_t *port, port_status_t *address, unsigned number,
    56   unsigned usec, ddf_dev_t *rh)
     52static int uhci_port_reset_enable(int portno, void *arg);
     53/*----------------------------------------------------------------------------*/
     54/** Initializes UHCI root hub port instance.
     55 *
     56 * @param[in] port Memory structure to use.
     57 * @param[in] addr Address of I/O register.
     58 * @param[in] number Port number.
     59 * @param[in] usec Polling interval.
     60 * @param[in] rh Pointer to ddf instance fo the root hub driver.
     61 * @return Error code.
     62 *
     63 * Starts the polling fibril.
     64 */
     65int uhci_port_init(uhci_port_t *port,
     66    port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh)
    5767{
    5868        assert(port);
     69
    5970        port->address = address;
    6071        port->number = number;
     
    6273        port->attached_device = 0;
    6374        port->rh = rh;
     75
    6476        int rc = usb_hc_connection_initialize_from_device(
    6577            &port->hc_connection, rh);
     
    7587                return ENOMEM;
    7688        }
     89
    7790        fibril_add_ready(port->checker);
    7891        usb_log_debug("Port(%p - %d): Added fibril. %x\n",
     
    8194}
    8295/*----------------------------------------------------------------------------*/
     96/** Finishes UHCI root hub port instance.
     97 *
     98 * @param[in] port Memory structure to use.
     99 *
     100 * Stops the polling fibril.
     101 */
    83102void uhci_port_fini(uhci_port_t *port)
    84103{
    85 // TODO: destroy fibril
    86 // TODO: hangup phone
    87 //      fibril_teardown(port->checker);
     104        /* TODO: Kill fibril here */
    88105        return;
    89106}
    90107/*----------------------------------------------------------------------------*/
     108/** Periodically checks port status and reports new devices.
     109 *
     110 * @param[in] port Memory structure to use.
     111 * @return Error code.
     112 */
    91113int uhci_port_check(void *port)
    92114{
    93         uhci_port_t *port_instance = port;
    94         assert(port_instance);
    95 //      port_status_write(port_instance->address, 0);
    96 
     115        uhci_port_t *instance = port;
     116        assert(instance);
     117
     118        /* Iteration count, for debug purposes only */
    97119        unsigned count = 0;
    98120
    99121        while (1) {
    100                 async_usleep(port_instance->wait_period_usec);
     122                async_usleep(instance->wait_period_usec);
    101123
    102124                /* read register value */
    103                 port_status_t port_status =
    104                         port_status_read(port_instance->address);
    105 
    106                 /* debug print */
    107                 static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
     125                port_status_t port_status = port_status_read(instance->address);
     126
     127                /* debug print mutex */
     128                static fibril_mutex_t dbg_mtx =
     129                    FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
    108130                fibril_mutex_lock(&dbg_mtx);
    109131                usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n",
    110                   port_instance->address, port_instance->number, port_status, count++);
     132                  instance->address, instance->number, port_status, count++);
    111133//              print_port_status(port_status);
    112134                fibril_mutex_unlock(&dbg_mtx);
    113135
    114                 if ((port_status & STATUS_CONNECTED_CHANGED) != 0) {
    115                         usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
    116                             port_instance->address, port_instance->number, port_status);
    117 
    118 
    119                         int rc = usb_hc_connection_open(
    120                             &port_instance->hc_connection);
    121                         if (rc != EOK) {
    122                                 usb_log_error("Port(%p - %d): Failed to connect to HC.",
    123                                     port_instance->address, port_instance->number);
    124                                 continue;
    125                         }
    126 
    127                         /* remove any old device */
    128                         if (port_instance->attached_device) {
    129                                 usb_log_debug("Port(%p - %d): Removing device.\n",
    130                                     port_instance->address, port_instance->number);
    131                                 uhci_port_remove_device(port_instance);
    132                         }
    133 
    134                         if ((port_status & STATUS_CONNECTED) != 0) {
    135                                 /* new device */
    136                                 uhci_port_new_device(port_instance, port_status);
    137                         } else {
    138                                 /* ack changes by writing one to WC bits */
    139                                 port_status_write(port_instance->address, port_status);
    140                                 usb_log_debug("Port(%p - %d): Change status ACK.\n",
    141                                                 port_instance->address, port_instance->number);
    142                         }
    143 
    144                         rc = usb_hc_connection_close(
    145                             &port_instance->hc_connection);
    146                         if (rc != EOK) {
    147                                 usb_log_error("Port(%p - %d): Failed to disconnect from HC.",
    148                                     port_instance->address, port_instance->number);
    149                         }
    150                 }
    151         }
    152         return EOK;
    153 }
    154 
     136                if ((port_status & STATUS_CONNECTED_CHANGED) == 0)
     137                        continue;
     138
     139                usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
     140                    instance->address, instance->number, port_status);
     141
     142                int rc =
     143                    usb_hc_connection_open(&instance->hc_connection);
     144                if (rc != EOK) {
     145                        usb_log_error("Port(%p - %d): Failed to connect to HC.",
     146                            instance->address, instance->number);
     147                        continue;
     148                }
     149
     150                /* Remove any old device */
     151                if (instance->attached_device) {
     152                        usb_log_debug2("Port(%p - %d): Removing device.\n",
     153                            instance->address, instance->number);
     154                        uhci_port_remove_device(instance);
     155                }
     156
     157                if ((port_status & STATUS_CONNECTED) != 0) {
     158                        /* New device */
     159                        const usb_speed_t speed =
     160                            ((port_status & STATUS_LOW_SPEED) != 0) ?
     161                            USB_SPEED_LOW : USB_SPEED_FULL;
     162                        uhci_port_new_device(instance, speed);
     163                } else {
     164                        /* Write one to WC bits, to ack changes */
     165                        port_status_write(instance->address, port_status);
     166                        usb_log_debug("Port(%p - %d): Change status ACK.\n",
     167                            instance->address, instance->number);
     168                }
     169
     170                rc = usb_hc_connection_close(&instance->hc_connection);
     171                if (rc != EOK) {
     172                        usb_log_error("Port(%p - %d): Failed to disconnect.",
     173                            instance->address, instance->number);
     174                }
     175        }
     176        return EOK;
     177}
     178/*----------------------------------------------------------------------------*/
    155179/** Callback for enabling port during adding a new device.
    156180 *
     
    159183 * @return Error code.
    160184 */
    161 static int new_device_enable_port(int portno, void *arg)
     185int uhci_port_reset_enable(int portno, void *arg)
    162186{
    163187        uhci_port_t *port = (uhci_port_t *) arg;
     
    184208                port_status_write(port->address, port_status);
    185209                async_usleep(10000);
    186                 port_status =
    187                         port_status_read(port->address);
     210                port_status = port_status_read(port->address);
    188211                port_status &= ~STATUS_IN_RESET;
    189212                port_status_write(port->address, port_status);
     
    194217        /* Enable the port. */
    195218        uhci_port_set_enabled(port, true);
    196 
    197         return EOK;
    198 }
    199 
    200 /*----------------------------------------------------------------------------*/
    201 static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
     219        return EOK;
     220}
     221/*----------------------------------------------------------------------------*/
     222/** Initializes and reports connected device.
     223 *
     224 * @param[in] port Memory structure to use.
     225 * @param[in] speed Detected speed.
     226 * @return Error code.
     227 *
     228 * Uses libUSB function to do the actual work.
     229 */
     230int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed)
    202231{
    203232        assert(port);
     
    209238        usb_address_t dev_addr;
    210239        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    211             ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
    212             new_device_enable_port, port->number, port,
     240            speed, uhci_port_reset_enable, port->number, port,
    213241            &dev_addr, &port->attached_device, NULL, NULL, NULL);
    214242
    215243        if (rc != EOK) {
    216                 usb_log_error("Port(%p-%d): Failed(%d) adding new device: %s.\n",
     244                usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n",
    217245                    port->address, port->number, rc, str_error(rc));
    218246                uhci_port_set_enabled(port, false);
     
    225253        return EOK;
    226254}
    227 
    228 /*----------------------------------------------------------------------------*/
    229 static int uhci_port_remove_device(uhci_port_t *port)
     255/*----------------------------------------------------------------------------*/
     256/** Removes device.
     257 *
     258 * @param[in] port Memory structure to use.
     259 * @return Error code.
     260 *
     261 * Does not work DDF does not support device removal.
     262 */
     263int uhci_port_remove_device(uhci_port_t *port)
    230264{
    231265        usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n",
    232                 port->address, port->number, (unsigned int)port->attached_device);
    233 //      uhci_port_set_enabled(port, false);
    234         return EOK;
    235 }
    236 /*----------------------------------------------------------------------------*/
    237 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
     266            port->address, port->number, (unsigned int)port->attached_device);
     267        return EOK;
     268}
     269/*----------------------------------------------------------------------------*/
     270/** Enables and disables port.
     271 *
     272 * @param[in] port Memory structure to use.
     273 * @return Error code. (Always EOK)
     274 */
     275int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
    238276{
    239277        assert(port);
    240278
    241         /* read register value */
    242         port_status_t port_status
    243                 = port_status_read(port->address);
    244 
    245         /* enable port: register write */
     279        /* Read register value */
     280        port_status_t port_status = port_status_read(port->address);
     281
     282        /* Set enabled bit */
    246283        if (enabled) {
    247284                port_status |= STATUS_ENABLED;
     
    249286                port_status &= ~STATUS_ENABLED;
    250287        }
     288
     289        /* Write new value. */
    251290        port_status_write(port->address, port_status);
    252291
  • uspace/drv/uhci-rhd/port_status.c

    r0588062e r8e9becf6  
    6060};
    6161
     62/** Prints portr status in a human readable way.
     63 *
     64 * @param[in] value Port value to print.
     65 * @return Error code.
     66 */
    6267void print_port_status(port_status_t value)
    6368{
  • uspace/drv/uhci-rhd/root_hub.c

    r0588062e r8e9becf6  
    4040#include "root_hub.h"
    4141
     42/** Initializes UHCI root hub instance.
     43 *
     44 * @param[in] instance Driver memory structure to use.
     45 * @param[in] addr Address of I/O registers.
     46 * @param[in] size Size of available I/O space.
     47 * @param[in] rh Pointer to ddf instance fo the root hub driver.
     48 * @return Error code.
     49 */
    4250int uhci_root_hub_init(
    4351  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh)
     
    4755        int ret;
    4856
    49         /* allow access to root hub registers */
    50         assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT == size);
     57        /* Allow access to root hub port registers */
     58        assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT <= size);
    5159        port_status_t *regs;
    5260        ret = pio_enable(addr, size, (void**)&regs);
    53 
    5461        if (ret < 0) {
    55                 usb_log_error("Failed to gain access to port registers at %p\n", regs);
     62                usb_log_error(
     63                    "Failed to gain access to port registers at %p\n", regs);
    5664                return ret;
    5765        }
     
    6068        unsigned i = 0;
    6169        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    62                 /* mind pointer arithmetics */
     70                /* NOTE: mind pointer arithmetics here */
    6371                ret = uhci_port_init(
    64                   &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
     72                    &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
    6573                if (ret != EOK) {
    6674                        unsigned j = 0;
     
    7482}
    7583/*----------------------------------------------------------------------------*/
    76 int uhci_root_hub_fini( uhci_root_hub_t* instance )
     84/** Finishes UHCI root hub instance.
     85 *
     86 * @param[in] instance Driver memory structure to use.
     87 * @return Error code.
     88 */
     89int uhci_root_hub_fini(uhci_root_hub_t* instance)
    7790{
    78         assert( instance );
    79         // TODO:
    80         //destroy fibril here
    81         //disable access to registers
     91        assert(instance);
     92        unsigned i = 0;
     93        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
     94                uhci_port_fini(&instance->ports[i]);
     95        }
    8296        return EOK;
    8397}
  • uspace/drv/usbhid/hiddev.c

    r0588062e r8e9becf6  
    206206        assert(endpoint_mapping[0].interface != NULL);
    207207       
     208        /*
     209         * Save polling interval
     210         */
     211        hid_dev->poll_interval = endpoint_mapping[0].descriptor->poll_interval;
     212        assert(hid_dev->poll_interval > 0);
     213       
    208214        rc = usbhid_dev_get_report_descriptor(hid_dev,
    209215            descriptors, descriptors_size,
  • uspace/drv/usbhid/hiddev.h

    r0588062e r8e9becf6  
    5757        usb_endpoint_pipe_t poll_pipe;
    5858       
     59        short poll_interval;
     60       
    5961        uint16_t iface;
    6062       
  • uspace/drv/usbhid/hidreq.c

    r0588062e r8e9becf6  
    6969                return sess_rc;
    7070        }
     71       
     72        uint16_t value = 0;
     73        value |= (type << 8);
    7174
    7275        usb_log_debug("Sending Set_Report request to the device.\n");
     
    7477        rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    7578            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    76             USB_HIDREQ_SET_REPORT, type, hid_dev->iface, buffer, buf_size);
     79            USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);
    7780
    7881        sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
     
    137140                return sess_rc;
    138141        }
     142       
     143        return EOK;
     144}
     145
     146/*----------------------------------------------------------------------------*/
     147
     148int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
     149{
     150        if (hid_dev == NULL) {
     151                usb_log_error("usbhid_req_set_idle(): no HID device "
     152                    "structure given.\n");
     153                return EINVAL;
     154        }
     155       
     156        /*
     157         * No need for checking other parameters, as they are checked in
     158         * the called function (usb_control_request_set()).
     159         */
     160       
     161        int rc, sess_rc;
     162       
     163        sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     164        if (sess_rc != EOK) {
     165                usb_log_warning("Failed to start a session: %s.\n",
     166                    str_error(sess_rc));
     167                return sess_rc;
     168        }
     169
     170        usb_log_debug("Sending Set_Idle request to the device ("
     171            "duration: %u, iface: %d).\n", duration, hid_dev->iface);
     172       
     173        uint16_t value = duration << 8;
     174       
     175        rc = usb_control_request_set(&hid_dev->ctrl_pipe,
     176            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     177            USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);
     178
     179        sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
     180
     181        if (rc != EOK) {
     182                usb_log_warning("Error sending output report to the keyboard: "
     183                    "%s.\n", str_error(rc));
     184                return rc;
     185        }
     186
     187        if (sess_rc != EOK) {
     188                usb_log_warning("Error closing session: %s.\n",
     189                    str_error(sess_rc));
     190                return sess_rc;
     191        }
     192       
     193        return EOK;
     194}
     195
     196/*----------------------------------------------------------------------------*/
     197
     198int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
     199    uint8_t *buffer, size_t buf_size, size_t *actual_size)
     200{
     201        if (hid_dev == NULL) {
     202                usb_log_error("usbhid_req_set_report(): no HID device structure"
     203                    " given.\n");
     204                return EINVAL;
     205        }
     206       
     207        /*
     208         * No need for checking other parameters, as they are checked in
     209         * the called function (usb_control_request_set()).
     210         */
     211       
     212        int rc, sess_rc;
     213       
     214        sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     215        if (sess_rc != EOK) {
     216                usb_log_warning("Failed to start a session: %s.\n",
     217                    str_error(sess_rc));
     218                return sess_rc;
     219        }
     220
     221        uint16_t value = 0;
     222        value |= (type << 8);
     223       
     224        usb_log_debug("Sending Get_Report request to the device.\n");
     225       
     226        rc = usb_control_request_get(&hid_dev->ctrl_pipe,
     227            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     228            USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,
     229            actual_size);
     230
     231        sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
     232
     233        if (rc != EOK) {
     234                usb_log_warning("Error sending output report to the keyboard: "
     235                    "%s.\n", str_error(rc));
     236                return rc;
     237        }
     238
     239        if (sess_rc != EOK) {
     240                usb_log_warning("Error closing session: %s.\n",
     241                    str_error(sess_rc));
     242                return sess_rc;
     243        }
     244       
     245        return EOK;
     246}
     247
     248int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
     249{
     250        if (hid_dev == NULL) {
     251                usb_log_error("usbhid_req_set_protocol(): no HID device "
     252                    "structure given.\n");
     253                return EINVAL;
     254        }
     255       
     256        /*
     257         * No need for checking other parameters, as they are checked in
     258         * the called function (usb_control_request_set()).
     259         */
     260       
     261        int rc, sess_rc;
     262       
     263        sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     264        if (sess_rc != EOK) {
     265                usb_log_warning("Failed to start a session: %s.\n",
     266                    str_error(sess_rc));
     267                return sess_rc;
     268        }
     269
     270        usb_log_debug("Sending Get_Protocol request to the device ("
     271            "iface: %d).\n", hid_dev->iface);
     272       
     273        uint8_t buffer[1];
     274        size_t actual_size = 0;
     275       
     276        rc = usb_control_request_get(&hid_dev->ctrl_pipe,
     277            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     278            USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);
     279
     280        sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
     281
     282        if (rc != EOK) {
     283                usb_log_warning("Error sending output report to the keyboard: "
     284                    "%s.\n", str_error(rc));
     285                return rc;
     286        }
     287
     288        if (sess_rc != EOK) {
     289                usb_log_warning("Error closing session: %s.\n",
     290                    str_error(sess_rc));
     291                return sess_rc;
     292        }
     293       
     294        if (actual_size != 1) {
     295                usb_log_warning("Wrong data size: %zu, expected: 1.\n",
     296                        actual_size);
     297                return ELIMIT;
     298        }
     299       
     300        *protocol = buffer[0];
     301       
     302        return EOK;
     303}
     304
     305int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
     306{
     307        if (hid_dev == NULL) {
     308                usb_log_error("usbhid_req_set_idle(): no HID device "
     309                    "structure given.\n");
     310                return EINVAL;
     311        }
     312       
     313        /*
     314         * No need for checking other parameters, as they are checked in
     315         * the called function (usb_control_request_set()).
     316         */
     317       
     318        int rc, sess_rc;
     319       
     320        sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     321        if (sess_rc != EOK) {
     322                usb_log_warning("Failed to start a session: %s.\n",
     323                    str_error(sess_rc));
     324                return sess_rc;
     325        }
     326
     327        usb_log_debug("Sending Get_Idle request to the device ("
     328            "iface: %d).\n", hid_dev->iface);
     329       
     330        uint16_t value = 0;
     331        uint8_t buffer[1];
     332        size_t actual_size = 0;
     333       
     334        rc = usb_control_request_get(&hid_dev->ctrl_pipe,
     335            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     336            USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,
     337            &actual_size);
     338
     339        sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
     340
     341        if (rc != EOK) {
     342                usb_log_warning("Error sending output report to the keyboard: "
     343                    "%s.\n", str_error(rc));
     344                return rc;
     345        }
     346
     347        if (sess_rc != EOK) {
     348                usb_log_warning("Error closing session: %s.\n",
     349                    str_error(sess_rc));
     350                return sess_rc;
     351        }
     352       
     353        if (actual_size != 1) {
     354                usb_log_warning("Wrong data size: %zu, expected: 1.\n",
     355                        actual_size);
     356                return ELIMIT;
     357        }
     358       
     359        *duration = buffer[0];
    139360       
    140361        return EOK;
  • uspace/drv/usbhid/hidreq.h

    r0588062e r8e9becf6  
    5050int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol);
    5151
     52int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration);
     53
     54int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
     55    uint8_t *buffer, size_t buf_size, size_t *actual_size);
     56
     57int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol);
     58
     59int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration);
     60
    5261/*----------------------------------------------------------------------------*/
    5362
  • uspace/drv/usbhid/kbddev.c

    r0588062e r8e9becf6  
    3838#include <str_error.h>
    3939#include <fibril.h>
     40#include <stdio.h>
    4041
    4142#include <io/keycode.h>
     
    6263static const size_t BOOTP_BUFFER_SIZE = 8;
    6364static const size_t BOOTP_BUFFER_OUT_SIZE = 1;
     65static const uint8_t BOOTP_ERROR_ROLLOVER = 1;
     66static const uint8_t IDLE_RATE = 0;
    6467
    6568/** Keyboard polling endpoint description for boot protocol class. */
     
    149152        uint8_t buffer[BOOTP_BUFFER_OUT_SIZE];
    150153        int rc= 0;
    151         unsigned i;
    152154       
    153155        memset(buffer, 0, BOOTP_BUFFER_OUT_SIZE);
     
    177179        }
    178180       
    179         // TODO: REFACTOR!!!
    180        
    181         usb_log_debug("Output report buffer: ");
    182         for (i = 0; i < BOOTP_BUFFER_OUT_SIZE; ++i) {
    183                 usb_log_debug("0x%x ", buffer[i]);
    184         }
    185         usb_log_debug("\n");
    186        
    187         uint16_t value = 0;
    188         value |= (USB_HID_REPORT_TYPE_OUTPUT << 8);
    189 
     181        usb_log_debug("Output report buffer: %s\n",
     182            usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0));
     183       
    190184        assert(kbd_dev->hid_dev != NULL);
    191185        assert(kbd_dev->hid_dev->initialized);
    192         usbhid_req_set_report(kbd_dev->hid_dev, value, buffer,
    193             BOOTP_BUFFER_OUT_SIZE);
     186        usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT,
     187            buffer, BOOTP_BUFFER_OUT_SIZE);
    194188}
    195189
     
    228222
    229223        if (mod_mask != 0) {
    230                 usb_log_debug2("\n\nChanging mods and lock keys\n");
    231                 usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods);
    232                 usb_log_debug2("\nLock keys before:0x%x\n\n",
    233                     kbd_dev->lock_keys);
    234                
    235224                if (type == KEY_PRESS) {
    236                         usb_log_debug2("\nKey pressed.\n");
    237225                        /*
    238226                         * Only change lock state on transition from released
     
    247235                        usbhid_kbd_set_led(kbd_dev);
    248236                } else {
    249                         usb_log_debug2("\nKey released.\n");
    250237                        kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
    251238                }
    252239        }
    253240
    254         usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods);
    255         usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys);
    256        
    257241        if (key == KC_CAPS_LOCK || key == KC_NUM_LOCK || key == KC_SCROLL_LOCK) {
    258242                // do not send anything to the console, this is our business
     
    281265        ev.key = key;
    282266        ev.mods = kbd_dev->mods;
    283        
    284         if (ev.mods & KM_NUM_LOCK) {
    285                 usb_log_debug("\n\nNum Lock turned on.\n\n");
    286         }
    287267
    288268        ev.c = layout[active_layout]->parse_ev(&ev);
     
    340320    const uint8_t *key_codes)
    341321{
    342         // TODO: phantom state!!
    343        
    344322        unsigned int key;
    345323        unsigned int i, j;
     324       
     325        /*
     326         * First of all, check if the kbd have reported phantom state.
     327         */
     328        i = 0;
     329        // all fields should report Error Rollover
     330        while (i < kbd_dev->keycode_count &&
     331            key_codes[i] == BOOTP_ERROR_ROLLOVER) {
     332                ++i;
     333        }
     334        if (i == kbd_dev->keycode_count) {
     335                usb_log_debug("Phantom state occured.\n");
     336                // phantom state, do nothing
     337                return;
     338        }
    346339       
    347340        // TODO: quite dummy right now, think of better implementation
     
    362355                        key = usbhid_parse_scancode(kbd_dev->keycodes[j]);
    363356                        usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    364                         usb_log_debug2("\nKey released: %d\n", key);
     357                        usb_log_debug2("Key released: %d\n", key);
    365358                } else {
    366359                        // found, nothing happens
     
    382375                        // not found, i.e. new key pressed
    383376                        key = usbhid_parse_scancode(key_codes[i]);
    384                         usb_log_debug2("\nKey pressed: %d (keycode: %d)\n", key,
     377                        usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    385378                            key_codes[i]);
    386379                        usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
     
    389382                }
    390383        }
     384//      // report all currently pressed keys
     385//      for (i = 0; i < kbd_dev->keycode_count; ++i) {
     386//              if (key_codes[i] != 0) {
     387//                      key = usbhid_parse_scancode(key_codes[i]);
     388//                      usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
     389//                          key_codes[i]);
     390//                      usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
     391//              }
     392//      }
    391393       
    392394        memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);
    393        
    394         usb_log_debug2("\nNew stored keycodes: ");
    395         for (i = 0; i < kbd_dev->keycode_count; ++i) {
    396                 usb_log_debug2("%d ", kbd_dev->keycodes[i]);
    397         }
     395
     396        usb_log_debug("New stored keycodes: %s\n",
     397            usb_debug_str_buffer(kbd_dev->keycodes, kbd_dev->keycode_count, 0));
    398398}
    399399
     
    410410                return;
    411411        }
    412 
    413         usb_log_debug2("Got keys from parser: ");
    414         unsigned i;
    415         for (i = 0; i < count; ++i) {
    416                 usb_log_debug2("%d ", key_codes[i]);
    417         }
    418         usb_log_debug2("\n");
    419412       
    420413        usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
    421414        assert(kbd_dev != NULL);
     415
     416        usb_log_debug("Got keys from parser: %s\n",
     417            usb_debug_str_buffer(key_codes, kbd_dev->keycode_count, 0));
    422418       
    423419        if (count != kbd_dev->keycode_count) {
     
    444440        callbacks->keyboard = usbhid_kbd_process_keycodes;
    445441
    446         //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
    447         //    NULL);
    448         /*usb_log_debug2("Calling usb_hid_boot_keyboard_input_report() with size"
    449             " %zu\n", actual_size);*/
    450         //dump_buffer("bufffer: ", buffer, actual_size);
     442        usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with "
     443            "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
    451444       
    452445        int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
     
    559552         * Set boot protocol.
    560553         * Set LEDs according to initial setup.
     554         * Set Idle rate
    561555         */
    562556        assert(kbd_dev->hid_dev != NULL);
     
    566560        usbhid_kbd_set_led(kbd_dev);
    567561       
     562        usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE);
     563       
    568564        kbd_dev->initialized = 1;
    569565        usb_log_info("HID/KBD device structure initialized.\n");
     
    593589
    594590        while (true) {
    595                 async_usleep(1000 * 10);
    596 
    597591                sess_rc = usb_endpoint_pipe_start_session(
    598592                    &kbd_dev->hid_dev->poll_pipe);
     
    635629                usb_log_debug("Calling usbhid_kbd_process_data()\n");
    636630                usbhid_kbd_process_data(kbd_dev, buffer, actual_size);
     631               
     632                // disabled for now, no reason to sleep
     633                //async_usleep(kbd_dev->hid_dev->poll_interval);
    637634        }
    638635
  • uspace/drv/usbhid/main.c

    r0588062e r8e9becf6  
    8080int main(int argc, char *argv[])
    8181{
    82         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     82        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    8383        return ddf_driver_main(&kbd_driver);
    8484}
  • uspace/drv/usbhub/usbhub.c

    r0588062e r8e9becf6  
    233233        dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction");
    234234        usb_endpoint_pipe_start_session(&result->endpoints.control);
     235        opResult = usb_request_set_configuration(&result->endpoints.control, 1);
     236        assert(opResult == EOK);
     237
    235238        opResult = usb_request_get_descriptor(&result->endpoints.control,
    236239                        USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     
    243246                dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult);
    244247                free(serialized_descriptor);
    245                 return result;
     248                free(result);
     249                return NULL;
    246250        }
    247251        dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor");
     
    249253        if(descriptor==NULL){
    250254                dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor ");
    251                 result->port_count = 1;///\TODO this code is only for debug!!!
    252                 return result;
     255                free(result);
     256                return NULL;
    253257        }
    254258
     
    286290
    287291        usb_hub_info_t * hub_info = usb_create_hub_info(dev);
     292        if(!hub_info){
     293                return EINTR;
     294        }
    288295
    289296        int opResult;
     
    294301        opResult = usb_hub_process_configuration_descriptors(hub_info);
    295302        if(opResult != EOK){
    296                 dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d",
     303                dprintf(USB_LOG_LEVEL_ERROR,"could not get configuration descriptors, %d",
    297304                                opResult);
    298305                return opResult;
  • uspace/drv/usbmid/main.c

    r0588062e r8e9becf6  
    4444#include "usbmid.h"
    4545
     46/** Callback when new MID device is attached to the host.
     47 *
     48 * @param gen_dev Generic DDF device representing the new device.
     49 * @return Error code.
     50 */
    4651static int usbmid_add_device(ddf_dev_t *gen_dev)
    4752{
     
    8691}
    8792
     93/** USB MID driver ops. */
    8894static driver_ops_t mid_driver_ops = {
    8995        .add_device = usbmid_add_device,
    9096};
    9197
     98/** USB MID driver. */
    9299static driver_t mid_driver = {
    93100        .name = NAME,
  • uspace/drv/usbmid/usbmid.c

    r0588062e r8e9becf6  
    6767}
    6868
     69/** DDF interface of the child - interface function. */
    6970static usb_iface_t child_usb_iface = {
    7071        .get_hc_handle = usb_iface_get_hc_handle_hub_child_impl,
     
    7374};
    7475
    75 
     76/** Operations for children - interface functions. */
    7677static ddf_dev_ops_t child_device_ops = {
    7778        .interfaces[USB_DEV_IFACE] = &child_usb_iface
    7879};
    7980
     81/** Operations of the device itself. */
    8082static ddf_dev_ops_t mid_device_ops = {
    8183        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
     
    123125/** Create new interface for USB MID device.
    124126 *
    125  * @param dev Backing generic DDF child device (representing interface).
     127 * @param fun Backing generic DDF device function (representing interface).
    126128 * @param iface_no Interface number.
    127129 * @return New interface.
  • uspace/drv/usbmid/usbmid.h

    r0588062e r8e9becf6  
    4444#define NAME "usbmid"
    4545
     46/** USB MID device container. */
    4647typedef struct {
    4748        /** Device container. */
     
    5455} usbmid_device_t;
    5556
     57
     58/** Container for single interface in a MID device. */
    5659typedef struct {
    5760        /** Function container. */
  • uspace/drv/usbmouse/init.c

    r0588062e r8e9becf6  
    101101
    102102static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     103/** Device ops for USB mouse. */
    103104static ddf_dev_ops_t mouse_ops = {
    104105        .default_handler = default_connection_handler
     
    107108/** Default handler for IPC methods not handled by DDF.
    108109 *
    109  * @param dev Device handling the call.
     110 * @param fun Device function handling the call.
    110111 * @param icallid Call id.
    111112 * @param icall Call data.
     
    135136}
    136137
    137 
     138/** Create USB mouse device.
     139 *
     140 * The mouse device is stored into <code>dev-&gt;driver_data</code>.
     141 *
     142 * @param dev Generic device.
     143 * @return Error code.
     144 */
    138145int usb_mouse_create(ddf_dev_t *dev)
    139146{
  • uspace/drv/usbmouse/main.c

    r0588062e r8e9becf6  
    3939#include <str_error.h>
    4040
     41/** Callback when new mouse device is attached and recognised by DDF.
     42 *
     43 * @param dev Representation of a generic DDF device.
     44 * @return Error code.
     45 */
    4146static int usbmouse_add_device(ddf_dev_t *dev)
    4247{
     
    6368}
    6469
     70/** USB mouse driver ops. */
    6571static driver_ops_t mouse_driver_ops = {
    6672        .add_device = usbmouse_add_device,
    6773};
    6874
     75/** USB mouse driver. */
    6976static driver_t mouse_driver = {
    7077        .name = NAME,
  • uspace/drv/usbmouse/mouse.c

    r0588062e r8e9becf6  
    3737#include <usb/debug.h>
    3838#include <errno.h>
     39#include <str_error.h>
    3940#include <ipc/mouse.h>
    4041
     42/** Fibril function for polling the mouse device.
     43 *
     44 * This function shall not terminate unless the device breaks and fails
     45 * to send data (e.g. stalls on data request).
     46 *
     47 * @param arg ddf_dev_t type representing the mouse device.
     48 * @return EOK Always.
     49 */
    4150int usb_mouse_polling_fibril(void *arg)
    4251{
     
    6473
    6574                size_t actual_size;
     75                int rc;
    6676
    67                 /* FIXME: check for errors. */
    68                 usb_endpoint_pipe_start_session(&mouse->poll_pipe);
     77                /*
     78                 * Error checking note:
     79                 * - failure when starting a session is considered
     80                 *   temporary (e.g. out of phones, next try might succeed)
     81                 * - failure of transfer considered fatal (probably the
     82                 *   device was unplugged)
     83                 * - session closing not checked (shall not fail anyway)
     84                 */
    6985
    70                 usb_endpoint_pipe_read(&mouse->poll_pipe,
     86                rc = usb_endpoint_pipe_start_session(&mouse->poll_pipe);
     87                if (rc != EOK) {
     88                        usb_log_warning("Failed to start session, will try again: %s.\n",
     89                            str_error(rc));
     90                        continue;
     91                }
     92
     93                rc = usb_endpoint_pipe_read(&mouse->poll_pipe,
    7194                    buffer, buffer_size, &actual_size);
    7295
    7396                usb_endpoint_pipe_end_session(&mouse->poll_pipe);
     97
     98                if (rc != EOK) {
     99                        usb_log_error("Failed reading mouse input: %s.\n",
     100                            str_error(rc));
     101                        break;
     102                }
     103
     104                usb_log_debug2("got buffer: %s.\n",
     105                    usb_debug_str_buffer(buffer, buffer_size, 0));
    74106
    75107                uint8_t butt = buffer[0];
     
    115147        }
    116148
     149        /*
     150         * Device was probably unplugged.
     151         * Hang-up the phone to the console.
     152         * FIXME: release allocated memory.
     153         */
     154        async_hangup(mouse->console_phone);
     155        mouse->console_phone = -1;
     156
     157        usb_log_error("Mouse polling fibril terminated.\n");
     158
    117159        return EOK;
    118160}
  • uspace/drv/usbmouse/mouse.h

    r0588062e r8e9becf6  
    4343#define NAME "usbmouse"
    4444
     45/** Container for USB mouse device. */
    4546typedef struct {
     47        /** Generic device container. */
    4648        ddf_dev_t *device;
     49        /** Function representing the device. */
    4750        ddf_fun_t *mouse_fun;
     51        /** Representation of connection to the device. */
    4852        usb_device_connection_t wire;
     53        /** Default (zero) control pipe. */
    4954        usb_endpoint_pipe_t ctrl_pipe;
     55        /** Polling (in) pipe. */
    5056        usb_endpoint_pipe_t poll_pipe;
     57        /** Polling interval in microseconds. */
    5158        suseconds_t poll_interval_us;
     59        /** IPC phone to console (consumer). */
    5260        int console_phone;
    5361} usb_mouse_t;
  • uspace/drv/vhc/conndev.c

    r0588062e r8e9becf6  
    110110/** Callback for DDF when client disconnects.
    111111 *
    112  * @param d Device the client was connected to.
     112 * @param fun Device function the client was connected to.
    113113 */
    114114void on_client_close(ddf_fun_t *fun)
  • uspace/lib/usb/Makefile

    r0588062e r8e9becf6  
    4747        src/request.c \
    4848        src/usb.c \
    49         src/usbdevice.c \
    50         src/usbmem.c
     49        src/usbdevice.c
    5150
    5251include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usb/include/usb/classes/classes.h

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief USB device classes and subclasses.
     33 * USB device classes (generic constants and functions).
    3434 */
    3535#ifndef LIBUSB_CLASSES_H_
  • uspace/lib/usb/include/usb/debug.h

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief Debugging related functions.
     33 * Debugging related functions.
    3434 */
    3535#ifndef LIBUSB_DEBUG_H_
     
    3939#include <assert.h>
    4040
    41 void usb_dprintf(const char *tag, int level, const char *format, ...);
    42 void usb_dprintf_enable(const char *tag, int level);
    43 
    4441void usb_dump_standard_descriptor(FILE *, const char *, const char *,
    4542    const uint8_t *, size_t);
     
    4744/** Logging level. */
    4845typedef enum {
     46        /** Fatal, unrecoverable, error.
     47         * Such error prevents the driver from working at all.
     48         */
    4949        USB_LOG_LEVEL_FATAL,
     50
     51        /** Serious but recoverable error
     52         * Shall be used for errors fatal for single device but not for
     53         * driver itself.
     54         */
    5055        USB_LOG_LEVEL_ERROR,
     56
     57        /** Warning.
     58         * Problems from which the driver is able to recover gracefully.
     59         */
    5160        USB_LOG_LEVEL_WARNING,
     61
     62        /** Information message.
     63         * This should be the last level that is printed by default to
     64         * the screen.
     65         * Typical usage is to inform that new device was found and what
     66         * are its capabilities.
     67         * Do not use for repetitive actions (such as device polling).
     68         */
    5269        USB_LOG_LEVEL_INFO,
     70
     71        /** Debugging message. */
    5372        USB_LOG_LEVEL_DEBUG,
     73
     74        /** More detailed debugging message. */
    5475        USB_LOG_LEVEL_DEBUG2,
     76
     77        /** Terminating constant for logging levels. */
    5578        USB_LOG_LEVEL_MAX
    5679} usb_log_level_t;
     
    6184void usb_log_printf(usb_log_level_t, const char *, ...);
    6285
     86/** Log fatal error. */
    6387#define usb_log_fatal(format, ...) \
    6488        usb_log_printf(USB_LOG_LEVEL_FATAL, format, ##__VA_ARGS__)
    6589
     90/** Log normal (recoverable) error. */
    6691#define usb_log_error(format, ...) \
    6792        usb_log_printf(USB_LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
    6893
     94/** Log warning. */
    6995#define usb_log_warning(format, ...) \
    7096        usb_log_printf(USB_LOG_LEVEL_WARNING, format, ##__VA_ARGS__)
    7197
     98/** Log informational message. */
    7299#define usb_log_info(format, ...) \
    73100        usb_log_printf(USB_LOG_LEVEL_INFO, format, ##__VA_ARGS__)
    74101
     102/** Log debugging message. */
    75103#define usb_log_debug(format, ...) \
    76104        usb_log_printf(USB_LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
    77105
     106/** Log verbose debugging message. */
    78107#define usb_log_debug2(format, ...) \
    79108        usb_log_printf(USB_LOG_LEVEL_DEBUG2, format, ##__VA_ARGS__)
    80109
     110const char *usb_debug_str_buffer(const uint8_t *, size_t, size_t);
    81111
    82112
  • uspace/lib/usb/include/usb/descriptor.h

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief Standard USB descriptors.
     33 * Standard USB descriptors.
    3434 */
    3535#ifndef LIBUSB_DESCRIPTOR_H_
     
    8383        /** Product descriptor index. */
    8484        uint8_t str_product;
    85         /** Device serial number desriptor index. */
     85        /** Device serial number descriptor index. */
    8686        uint8_t str_serial_number;
    8787        /** Number of possible configurations. */
     
    167167} __attribute__ ((packed)) usb_standard_endpoint_descriptor_t;
    168168
    169 
    170 /* TODO: string descriptors. */
    171 
    172169#endif
    173170/**
  • uspace/lib/usb/include/usb/dp.h

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief USB descriptor parser.
     33 * USB descriptor parser.
    3434 */
    3535#ifndef LIBUSB_DP_H_
     
    4040#include <usb/descriptor.h>
    4141
     42/** USB descriptors nesting.
     43 * The nesting describes the logical tree USB descriptors form
     44 * (e.g. that endpoint descriptor belongs to interface or that
     45 * interface belongs to configuration).
     46 *
     47 * See usb_descriptor_type_t for descriptor constants.
     48 */
    4249typedef struct {
     50        /** Child descriptor id. */
    4351        int child;
     52        /** Parent descriptor id. */
    4453        int parent;
    4554} usb_dp_descriptor_nesting_t;
     
    4756extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];
    4857
     58/** Descriptor parser structure. */
    4959typedef struct {
     60        /** Used descriptor nesting. */
    5061        usb_dp_descriptor_nesting_t *nesting;
    5162} usb_dp_parser_t;
    5263
     64/** Descriptor parser data. */
    5365typedef struct {
     66        /** Data to be parsed. */
    5467        uint8_t *data;
     68        /** Size of input data in bytes. */
    5569        size_t size;
     70        /** Custom argument. */
    5671        void *arg;
    5772} usb_dp_parser_data_t;
  • uspace/lib/usb/include/usb/hub.h

    r0588062e r8e9becf6  
    3232/** @file
    3333 * Functions needed by hub drivers.
     34 *
     35 * For class specific requests, see usb/classes/hub.h.
    3436 */
    3537#ifndef LIBUSB_HUB_H_
  • uspace/lib/usb/include/usb/pipes.h

    r0588062e r8e9becf6  
    4343#include <ddf/driver.h>
    4444
    45 /**
    46  * Abstraction of a physical connection to the device.
     45/** Abstraction of a physical connection to the device.
    4746 * This type is an abstraction of the USB wire that connects the host and
    4847 * the function (device).
     
    5554} usb_device_connection_t;
    5655
    57 /**
    58  * Abstraction of a logical connection to USB device endpoint.
     56/** Abstraction of a logical connection to USB device endpoint.
    5957 * It encapsulates endpoint attributes (transfer type etc.) as well
    6058 * as information about currently running sessions.
     
    111109        /** Found descriptor fitting the description. */
    112110        usb_standard_endpoint_descriptor_t *descriptor;
    113         /** Interface the endpoint belongs to. */
     111        /** Interface descriptor the endpoint belongs to. */
    114112        usb_standard_interface_descriptor_t *interface;
    115113        /** Whether the endpoint was actually found. */
  • uspace/lib/usb/include/usb/request.h

    r0588062e r8e9becf6  
    7272        union {
    7373                uint16_t value;
    74                 /* FIXME: add #ifdefs according to host endianess */
     74                /* FIXME: add #ifdefs according to host endianness */
    7575                struct {
    7676                        uint8_t value_low;
  • uspace/lib/usb/include/usb/usb.h

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief Base USB types.
     33 * Common USB types and functions.
    3434 */
    3535#ifndef LIBUSB_USB_H_
     
    121121} usb_target_t;
    122122
     123/** Compare USB targets (addresses and endpoints).
     124 *
     125 * @param a First target.
     126 * @param b Second target.
     127 * @return Whether @p a and @p b points to the same pipe on the same device.
     128 */
    123129static inline int usb_target_same(usb_target_t a, usb_target_t b)
    124130{
  • uspace/lib/usb/src/ddfiface.c

    r0588062e r8e9becf6  
    5656/** Get host controller handle, interface implementation for hub driver.
    5757 *
    58  * @param[in] device Device the operation is running on.
     58 * @param[in] fun Device function the operation is running on.
    5959 * @param[out] handle Storage for the host controller handle.
    6060 * @return Error code.
     
    6969 * a hub driver.
    7070 *
    71  * @param[in] device Device the operation is running on.
     71 * @param[in] fun Device function the operation is running on.
    7272 * @param[out] handle Storage for the host controller handle.
    7373 * @return Error code.
     
    8888            IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle);
    8989
     90        async_hangup(parent_phone);
     91
    9092        if (rc != EOK) {
    9193                return rc;
     
    99101/** Get host controller handle, interface implementation for HC driver.
    100102 *
    101  * @param[in] device Device the operation is running on.
     103 * @param[in] fun Device function the operation is running on.
    102104 * @param[out] handle Storage for the host controller handle.
    103105 * @return Always EOK.
     
    116118/** Get USB device address, interface implementation for hub driver.
    117119 *
    118  * @param[in] device Device the operation is running on.
     120 * @param[in] fun Device function the operation is running on.
    119121 * @param[in] handle Devman handle of USB device we want address of.
    120122 * @param[out] address Storage for USB address of device with handle @p handle.
     
    151153 * a hub driver.
    152154 *
    153  * @param[in] device Device the operation is running on.
     155 * @param[in] fun Device function the operation is running on.
    154156 * @param[in] handle Devman handle of USB device we want address of.
    155157 * @param[out] address Storage for USB address of device with handle @p handle.
  • uspace/lib/usb/src/debug.c

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief Debugging support.
     33 * Debugging and logging support.
    3434 */
    3535#include <adt/list.h>
     
    4040#include <usb/debug.h>
    4141
    42 /** Debugging tag. */
    43 typedef struct {
    44         /** Linked list member. */
    45         link_t link;
    46         /** Tag name.
    47          * We always have a private copy of the name.
    48          */
    49         char *tag;
    50         /** Enabled level of debugging. */
    51         int level;
    52 } usb_debug_tag_t;
    53 
    54 /** Get instance of usb_debug_tag_t from link_t. */
    55 #define USB_DEBUG_TAG_INSTANCE(iterator) \
    56         list_get_instance(iterator, usb_debug_tag_t, link)
    57 
    58 /** List of all known tags. */
    59 static LIST_INITIALIZE(tag_list);
    60 /** Mutex guard for the list of all tags. */
    61 static FIBRIL_MUTEX_INITIALIZE(tag_list_guard);
    62 
    6342/** Level of logging messages. */
    6443static usb_log_level_t log_level = USB_LOG_LEVEL_WARNING;
     44
    6545/** Prefix for logging messages. */
    6646static const char *log_prefix = "usb";
     47
    6748/** Serialization mutex for logging functions. */
    6849static FIBRIL_MUTEX_INITIALIZE(log_serializer);
     50
     51/** File where to store the log. */
    6952static FILE *log_stream = NULL;
    7053
    71 /** Find or create new tag with given name.
    72  *
    73  * @param tagname Tag name.
    74  * @return Debug tag structure.
    75  * @retval NULL Out of memory.
    76  */
    77 static usb_debug_tag_t *get_tag(const char *tagname)
    78 {
    79         link_t *link;
    80         for (link = tag_list.next; \
    81             link != &tag_list; \
    82             link = link->next) {
    83                 usb_debug_tag_t *tag = USB_DEBUG_TAG_INSTANCE(link);
    84                 if (str_cmp(tag->tag, tagname) == 0) {
    85                         return tag;
    86                 }
    87         }
    88 
    89         /*
    90          * Tag not found, we will create a new one.
    91          */
    92         usb_debug_tag_t *new_tag = malloc(sizeof(usb_debug_tag_t));
    93         int rc = asprintf(&new_tag->tag, "%s", tagname);
    94         if (rc < 0) {
    95                 free(new_tag);
    96                 return NULL;
    97         }
    98         list_initialize(&new_tag->link);
    99         new_tag->level = 1;
    100 
    101         /*
    102          * Append it to the end of known tags.
    103          */
    104         list_append(&new_tag->link, &tag_list);
    105 
    106         return new_tag;
    107 }
    108 
    109 /** Print debugging information.
    110  * If the tag is used for the first time, its structures are automatically
    111  * created and initial verbosity level is set to 1.
    112  *
    113  * @param tagname Tag name.
    114  * @param level Level (verbosity) of the message.
    115  * @param format Formatting string for printf().
    116  */
    117 void usb_dprintf(const char *tagname, int level, const char *format, ...)
    118 {
    119         fibril_mutex_lock(&tag_list_guard);
    120         usb_debug_tag_t *tag = get_tag(tagname);
    121         if (tag == NULL) {
    122                 printf("USB debug: FATAL ERROR - failed to create tag.\n");
    123                 goto leave;
    124         }
    125 
    126         if (tag->level < level) {
    127                 goto leave;
    128         }
    129 
    130         va_list args;
    131         va_start(args, format);
    132 
    133         printf("[%s:%d]: ", tagname, level);
    134         vprintf(format, args);
    135 
    136         va_end(args);
    137 
    138 leave:
    139         fibril_mutex_unlock(&tag_list_guard);
    140 }
    141 
    142 /** Enable debugging prints for given tag.
    143  *
    144  * Setting level to <i>n</i> will cause that only printing messages
    145  * with level lower or equal to <i>n</i> will be printed.
    146  *
    147  * @param tagname Tag name.
    148  * @param level Enabled level.
    149  */
    150 void usb_dprintf_enable(const char *tagname, int level)
    151 {
    152         fibril_mutex_lock(&tag_list_guard);
    153         usb_debug_tag_t *tag = get_tag(tagname);
    154         if (tag == NULL) {
    155                 printf("USB debug: FATAL ERROR - failed to create tag.\n");
    156                 goto leave;
    157         }
    158 
    159         tag->level = level;
    160 
    161 leave:
    162         fibril_mutex_unlock(&tag_list_guard);
    163 }
    16454
    16555/** Enable logging.
     
    18272}
    18373
    184 
     74/** Get log level name prefix.
     75 *
     76 * @param level Log level.
     77 * @return String prefix for the message.
     78 */
    18579static const char *log_level_name(usb_log_level_t level)
    18680{
     
    252146}
    253147
     148
     149#define REMAINDER_STR_FMT " (%zu)..."
     150/* string + terminator + number width (enough for 4GB)*/
     151#define REMAINDER_STR_LEN (5 + 1 + 10)
     152
     153/** How many bytes to group together. */
     154#define BUFFER_DUMP_GROUP_SIZE 4
     155
     156/** Size of the string for buffer dumps. */
     157#define BUFFER_DUMP_LEN 240 /* Ought to be enough for everybody ;-). */
     158
     159/** Fibril local storage for the dumped buffer. */
     160static fibril_local char buffer_dump[BUFFER_DUMP_LEN];
     161
     162/** Dump buffer into string.
     163 *
     164 * The function dumps given buffer into hexadecimal format and stores it
     165 * in a static fibril local string.
     166 * That means that you do not have to deallocate the string (actually, you
     167 * can not do that) and you do not have to guard it against concurrent
     168 * calls to it.
     169 * The only limitation is that each call rewrites the buffer again.
     170 * Thus, it is necessary to copy the buffer elsewhere (that includes printing
     171 * to screen or writing to file).
     172 * Since this function is expected to be used for debugging prints only,
     173 * that is not a big limitation.
     174 *
     175 * @warning You cannot use this function twice in the same printf
     176 * (see detailed explanation).
     177 *
     178 * @param buffer Buffer to be printed (can be NULL).
     179 * @param size Size of the buffer in bytes (can be zero).
     180 * @param dumped_size How many bytes to actually dump (zero means all).
     181 * @return Dumped buffer as a static (but fibril local) string.
     182 */
     183const char *usb_debug_str_buffer(const uint8_t *buffer, size_t size,
     184    size_t dumped_size)
     185{
     186        /*
     187         * Remove previous string (that might also reveal double usage of
     188         * this function).
     189         */
     190        bzero(buffer_dump, BUFFER_DUMP_LEN);
     191
     192        if (buffer == NULL) {
     193                return "(null)";
     194        }
     195        if (size == 0) {
     196                return "(empty)";
     197        }
     198        if ((dumped_size == 0) || (dumped_size > size)) {
     199                dumped_size = size;
     200        }
     201
     202        /* How many bytes are available in the output buffer. */
     203        size_t buffer_remaining_size = BUFFER_DUMP_LEN - 1 - REMAINDER_STR_LEN;
     204        char *it = buffer_dump;
     205
     206        size_t index = 0;
     207
     208        while (index < size) {
     209                /* Determine space before the number. */
     210                const char *space_before;
     211                if (index == 0) {
     212                        space_before = "";
     213                } else if ((index % BUFFER_DUMP_GROUP_SIZE) == 0) {
     214                        space_before = "  ";
     215                } else {
     216                        space_before = " ";
     217                }
     218
     219                /*
     220                 * Add the byte as a hexadecimal number plus the space.
     221                 * We do it into temporary buffer to ensure that always
     222                 * the whole byte is printed.
     223                 */
     224                int val = buffer[index];
     225                char current_byte[16];
     226                int printed = snprintf(current_byte, 16,
     227                    "%s%02x", space_before, val);
     228                if (printed < 0) {
     229                        break;
     230                }
     231
     232                if ((size_t) printed > buffer_remaining_size) {
     233                        break;
     234                }
     235
     236                /* We can safely add 1, because space for end 0 is reserved. */
     237                str_append(it, buffer_remaining_size + 1, current_byte);
     238
     239                buffer_remaining_size -= printed;
     240                /* Point at the terminator 0. */
     241                it += printed;
     242                index++;
     243
     244                if (index >= dumped_size) {
     245                        break;
     246                }
     247        }
     248
     249        /* Add how many bytes were not printed. */
     250        if (index < size) {
     251                snprintf(it, REMAINDER_STR_LEN,
     252                    REMAINDER_STR_FMT, size - index);
     253        }
     254
     255        return buffer_dump;
     256}
     257
     258
    254259/**
    255260 * @}
  • uspace/lib/usb/src/dp.c

    r0588062e r8e9becf6  
    3232/**
    3333 * @file
    34  * @brief USB descriptor parser (implementation).
     34 * USB descriptor parser (implementation).
     35 *
     36 * The descriptor parser is a generic parser for structure, where individual
     37 * items are stored in single buffer and each item begins with length followed
     38 * by type. These types are organized into tree hierarchy.
     39 *
     40 * The parser is able of only two actions: find first child and find next
     41 * sibling.
    3542 */
    3643#include <stdio.h>
  • uspace/lib/usb/src/dump.c

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief Descriptor dumping.
     33 * Descriptor dumping.
    3434 */
    3535#include <adt/list.h>
     
    4343#include <usb/classes/hid.h>
    4444
     45/** Mapping between descriptor id and dumping function. */
    4546typedef struct {
     47        /** Descriptor id. */
    4648        int id;
     49        /** Dumping function. */
    4750        void (*dump)(FILE *, const char *, const char *,
    4851            const uint8_t *, size_t);
     
    6669    const uint8_t *, size_t);
    6770
     71/** Descriptor dumpers mapping. */
    6872static descriptor_dump_t descriptor_dumpers[] = {
    6973        { USB_DESCTYPE_DEVICE, usb_dump_descriptor_device },
     
    273277    const uint8_t *descriptor, size_t descriptor_length)
    274278{
     279        /* TODO */
    275280}
    276281
     
    279284    const uint8_t *descriptor, size_t descriptor_length)
    280285{
     286        /* TODO */
    281287}
    282288
  • uspace/lib/usb/src/hub.c

    r0588062e r8e9becf6  
    5757 *
    5858 * @param connection Opened connection to host controller.
     59 * @param speed Speed of the device that will respond on the default address.
    5960 * @return Error code.
    6061 */
     
    8687 *
    8788 * @param connection Opened connection to host controller.
     89 * @param speed Speed of the new device (device that will be assigned
     90 *    the returned address).
    8891 * @return Assigned USB address or negative error code.
    8992 */
     
    144147/** Wrapper for registering attached device to the hub.
    145148 *
    146  * The @p enable_port function is expected to enable singalling on given
     149 * The @p enable_port function is expected to enable signaling on given
    147150 * port.
    148151 * The two arguments to it can have arbitrary meaning
     
    152155 *
    153156 * If the @p enable_port fails (i.e. does not return EOK), the device
    154  * addition is cancelled.
     157 * addition is canceled.
    155158 * The return value is then returned (it is good idea to use different
    156159 * error codes than those listed as return codes by this function itself).
    157160 *
    158  * @param parent Parent device (i.e. the hub device).
    159  * @param connection Opened connection to host controller.
    160  * @param dev_speed New device speed.
    161  * @param enable_port Function for enabling signalling through the port the
     161 * @param[in] parent Parent device (i.e. the hub device).
     162 * @param[in] connection Opened connection to host controller.
     163 * @param[in] dev_speed New device speed.
     164 * @param[in] enable_port Function for enabling signaling through the port the
    162165 *      device is attached to.
    163  * @param port_no Port number (passed through to @p enable_port).
    164  * @param arg Any data argument to @p enable_port.
     166 * @param[in] port_no Port number (passed through to @p enable_port).
     167 * @param[in] arg Any data argument to @p enable_port.
    165168 * @param[out] assigned_address USB address of the device.
    166169 * @param[out] assigned_handle Devman handle of the new device.
     170 * @param[in] dev_ops Child device ops.
     171 * @param[in] new_dev_data Arbitrary pointer to be stored in the child
     172 *      as @c driver_data.
     173 * @param[out] new_fun Storage where pointer to allocated child function
     174 *      will be written.
    167175 * @return Error code.
    168176 * @retval ENOENT Connection to HC not opened.
     
    201209
    202210        /*
    203          * Enable the port (i.e. allow signalling through this port).
     211         * Enable the port (i.e. allow signaling through this port).
    204212         */
    205213        rc = enable_port(port_no, arg);
  • uspace/lib/usb/src/pipes.c

    r0588062e r8e9becf6  
    9999 *
    100100 * @param connection Connection structure to be initialized.
    101  * @param device Generic device backing the USB device.
     101 * @param dev Generic device backing the USB device.
    102102 * @return Error code.
    103103 */
  • uspace/lib/usb/src/pipesio.c

    r0588062e r8e9becf6  
    115115
    116116        if (data_request_rc != EOK) {
    117                 return (int) data_request_rc;
     117                /* Prefer the return code of the opening request. */
     118                if (opening_request_rc != EOK) {
     119                        return (int) opening_request_rc;
     120                } else {
     121                        return (int) data_request_rc;
     122                }
    118123        }
    119124        if (opening_request_rc != EOK) {
     
    331336
    332337        if (data_request_rc != EOK) {
    333                 return (int) data_request_rc;
     338                /* Prefer the return code of the opening request. */
     339                if (opening_request_rc != EOK) {
     340                        return (int) opening_request_rc;
     341                } else {
     342                        return (int) data_request_rc;
     343                }
    334344        }
    335345        if (opening_request_rc != EOK) {
  • uspace/lib/usb/src/recognise.c

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief Functions for recognising kind of attached devices.
     33 * Functions for recognition of attached devices.
    3434 */
    3535#include <sys/types.h>
     
    4444#include <assert.h>
    4545
     46/** Index to append after device name for uniqueness. */
    4647static size_t device_name_index = 0;
     48/** Mutex guard for device_name_index. */
    4749static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);
    4850
     51/** DDF operations of child devices. */
    4952ddf_dev_ops_t child_ops = {
    5053        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    5154};
    5255
     56/** Get integer part from BCD coded number. */
    5357#define BCD_INT(a) (((unsigned int)(a)) / 256)
     58/** Get fraction part from BCD coded number (as an integer, no less). */
    5459#define BCD_FRAC(a) (((unsigned int)(a)) % 256)
    5560
     61/** Format for BCD coded number to be used in printf. */
    5662#define BCD_FMT "%x.%x"
     63/** Arguments to printf for BCD coded number. */
    5764#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
    5865
     
    113120}
    114121
     122/** Add match id to list or return with error code.
     123 *
     124 * @param match_ids List of match ids.
     125 * @param score Match id score.
     126 * @param format Format of the matching string
     127 * @param ... Arguments for the format.
     128 */
    115129#define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
    116130        do { \
     
    124138/** Create device match ids based on its interface.
    125139 *
    126  * @param[in] descriptor Interface descriptor.
     140 * @param[in] desc_device Device descriptor.
     141 * @param[in] desc_interface Interface descriptor.
    127142 * @param[out] matches Initialized list of match ids.
    128143 * @return Error code (the two mentioned are not the only ones).
    129144 * @retval EINVAL Invalid input parameters (expects non NULL pointers).
    130  * @retval ENOENT Interface does not specify class.
     145 * @retval ENOENT Device class is not "use interface".
    131146 */
    132147int usb_device_create_match_ids_from_interface(
     
    319334 * @param[in] parent Parent device.
    320335 * @param[out] child_handle Handle of the child device.
     336 * @param[in] dev_ops Child device ops.
     337 * @param[in] dev_data Arbitrary pointer to be stored in the child
     338 *      as @c driver_data.
     339 * @param[out] child_fun Storage where pointer to allocated child function
     340 *      will be written.
    321341 * @return Error code.
    322342 */
  • uspace/lib/usb/src/request.c

    r0588062e r8e9becf6  
    110110  *     (must be in USB endianness).
    111111  * @param data Buffer where to store data accepted during the DATA stage.
    112   *     (they will come in USB endianess).
     112  *     (they will come in USB endianness).
    113113  * @param data_size Size of the @p data buffer
    114114  *     (in native endianness).
     
    161161 * the new address.
    162162 *
    163  * @see usb_drv_reserve_default_address
    164  * @see usb_drv_release_default_address
    165  * @see usb_drv_request_address
    166  * @see usb_drv_release_address
    167  * @see usb_drv_bind_address
    168  *
    169163 * @param pipe Control endpoint pipe (session must be already started).
    170164 * @param new_address New USB address to be set (in native endianness).
     
    201195 * @param[in] pipe Control endpoint pipe (session must be already started).
    202196 * @param[in] request_type Request type (standard/class/vendor).
     197 * @param[in] recipient Request recipient (device/interface/endpoint).
    203198 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
    204199 * @param[in] descriptor_index Descriptor index.
     
    235230 * @param[in] pipe Control endpoint pipe (session must be already started).
    236231 * @param[in] request_type Request type (standard/class/vendor).
     232 * @param[in] recipient Request recipient (device/interface/endpoint).
    237233 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
    238234 * @param[in] descriptor_index Descriptor index.
     
    528524                return EEMPTY;
    529525        }
    530         /* Substract first 2 bytes (length and descriptor type). */
     526        /* Subtract first 2 bytes (length and descriptor type). */
    531527        string_descriptor_size -= 2;
    532528
     
    548544        size_t i;
    549545        for (i = 0; i < langs_count; i++) {
    550                 /* Language code from the descriptor is in USB endianess. */
     546                /* Language code from the descriptor is in USB endianness. */
    551547                /* FIXME: is this really correct? */
    552548                uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
     
    569565 *
    570566 * @param[in] pipe Control endpoint pipe (session must be already started).
    571  * @param[in] index String index (in native endianess),
     567 * @param[in] index String index (in native endianness),
    572568 *      first index has number 1 (index from descriptors can be used directly).
    573  * @param[in] lang String language (in native endianess).
     569 * @param[in] lang String language (in native endianness).
    574570 * @param[out] string_ptr Where to store allocated string in native encoding.
    575571 * @return Error code.
     
    613609                goto leave;
    614610        }
    615         /* Substract first 2 bytes (length and descriptor type). */
     611        /* Subtract first 2 bytes (length and descriptor type). */
    616612        string_size -= 2;
    617613
  • uspace/lib/usb/src/usb.c

    r0588062e r8e9becf6  
    3131 */
    3232/** @file
    33  * @brief Base USB types.
     33 * Common USB functions.
    3434 */
    3535#include <usb/usb.h>
     
    3737
    3838
    39 /** String representation for USB transfer type. */
     39/** String representation for USB transfer type.
     40 *
     41 * @param t Transfer type.
     42 * @return Transfer type as a string (in English).
     43 */
    4044const char * usb_str_transfer_type(usb_transfer_type_t t)
    4145{
Note: See TracChangeset for help on using the changeset viewer.